热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

NestedtransactionsinstoredprocedureofSQLServer

question:ifthenestedtransactionencounteredanexception,thenrollbacked.Howabouttheouter

question:

if the nested transaction encountered an exception, then rollbacked. How about the outer transaction?

Lets demo this using below code.

create procedure sp1 BEGIN 

BEGIN TRANSACTION ... exec sp2 COMMIT
END

Now, if SP 2 - rolls back for whatever reason, does SP 1 - commit or rollback or throw exception? 

Answer:

The outer transaction will be rollbacked as well.

There are no autonomous transactions in SQL Server. You may see @@TRANCOUNT increase beyond 1, but a rollback affects the whole thing.

 

Outer proc:

CREATE PROCEDURE dbo.sp1 @trip BIT
AS
BEGIN
    SET NOCOUNT ON; BEGIN TRANSACTION; PRINT @@TRANCOUNT; BEGIN TRY EXEC dbo.sp2 @trip = @trip; END TRY BEGIN CATCH PRINT ERROR_MESSAGE(); END CATCH PRINT @@TRANCOUNT; IF @@TRANCOUNT > 0
        COMMIT TRANSACTION; PRINT @@TRANCOUNT; END
GO

 

Inner proc:

CREATE PROCEDURE dbo.sp2 @trip BIT
AS
BEGIN
    SET NOCOUNT ON; BEGIN TRANSACTION; PRINT @@TRANCOUNT; IF @trip = 1
    BEGIN
        IF @@TRANCOUNT > 0
            ROLLBACK TRANSACTION; END
    ELSE
    BEGIN   
        IF @@TRANCOUNT > 0
            COMMIT TRANSACTION; END

    PRINT @@TRANCOUNT; END
GO

 

So now let's call it and let everything commit:

EXEC dbo.sp1 @trip = 0;

Results:

1
2
1
1
0

Now let's call it and roll back the inner procedure:

EXEC dbo.sp1 @trip = 1;

Results:

1
2
0 <-- notice that a rollback here rolled back both
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0.
0
0

 

Explicit transactions can be nested. This is primarily intended to support transactions in stored procedures that can be called either from a process already in a transaction or from processes that have no active transaction.

The following example shows the intended use of nested transactions. The procedure TransProc enforces its transaction regardless of the transaction mode of any process that executes it. If TransProc is called when a transaction is active, the nested transaction in TransProc is largely ignored, and its INSERT statements are committed or rolled back based on the final action taken for the outer transaction. If TransProc is executed by a process that does not have an outstanding transaction, the COMMIT TRANSACTION at the end of the procedure effectively commits the INSERT statements.

 
 
SET QUOTED_IDENTIFIER OFF; GO
SET NOCOUNT OFF; GO
USE AdventureWorks2008R2; GO
CREATE TABLE TestTrans(Cola INT PRIMARY KEY, Colb CHAR(3) NOT NULL); GO
CREATE PROCEDURE TransProc @PriKey INT, @CharCol CHAR(3) AS
BEGIN TRANSACTION InProc INSERT INTO TestTrans VALUES (@PriKey, @CharCol) INSERT INTO TestTrans VALUES (@PriKey + 1, @CharCol) COMMIT TRANSACTION InProc; GO
/* Start a transaction and execute TransProc. */
BEGIN TRANSACTION OutOfProc; GO
EXEC TransProc 1, 'aaa'; GO
/* Roll back the outer transaction, this will roll back TransProc's nested transaction. */
ROLLBACK TRANSACTION OutOfProc; GO
EXECUTE TransProc 3,'bbb'; GO
/* The following SELECT statement shows only rows 3 and 4 are still in the table. This indicates that the commit of the inner transaction from the first EXECUTE statement of TransProc was overridden by the subsequent rollback. */
SELECT * FROM TestTrans; GO

 

Committing inner transactions is ignored by the SQL Server Database Engine. The transaction is either committed or rolled back based on the action taken at the end of the outermost transaction. If the outer transaction is committed, the inner nested transactions are also committed. If the outer transaction is rolled back, then all inner transactions are also rolled back, regardless of whether or not the inner transactions were individually committed.

Each call to COMMIT TRANSACTION or COMMIT WORK applies to the last executed BEGIN TRANSACTION. If the BEGIN TRANSACTION statements are nested, then a COMMIT statement applies only to the last nested transaction, which is the innermost transaction. Even if a COMMIT TRANSACTION transaction_namestatement within a nested transaction refers to the transaction name of the outer transaction, the commit applies only to the innermost transaction.

It is not legal for the transaction_name parameter of a ROLLBACK TRANSACTION statement to refer to the inner transactions of a set of named nested transactions. transaction_name can refer only to the transaction name of the outermost transaction. If a ROLLBACK TRANSACTION transaction_name statement using the name of the outer transaction is executed at any level of a set of nested transactions, all of the nested transactions are rolled back. If a ROLLBACK WORK or ROLLBACK TRANSACTION statement without a transaction_name parameter is executed at any level of a set of nested transaction, it rolls back all of the nested transactions, including the outermost transaction.

The @@TRANCOUNT function records the current transaction nesting level. Each BEGIN TRANSACTION statement increments @@TRANCOUNT by one. Each COMMIT TRANSACTION or COMMIT WORK statement decrements @@TRANCOUNT by one. A ROLLBACK WORK or a ROLLBACK TRANSACTION statement that does not have a transaction name rolls back all nested transactions and decrements @@TRANCOUNT to 0. A ROLLBACK TRANSACTION that uses the transaction name of the outermost transaction in a set of nested transactions rolls back all of the nested transactions and decrements @@TRANCOUNT to 0. When you are unsure if you are already in a transaction, SELECT @@TRANCOUNT to determine if it is 1 or more. If @@TRANCOUNT is 0, you are not in a transaction.

Reference
@@TRANCOUNT (Transact-SQL)
BEGIN TRANSACTION (Transact-SQL)
COMMIT TRANSACTION (Transact-SQL)
ROLLBACK TRANSACTION (Transact-SQL)
COMMIT WORK (Transact-SQL)
ROLLBACK WORK (Transact-SQL)
 
整理自
http://technet.microsoft.com/en-us/library/ms189336%28v=sql.105%29.aspx
http://stackoverflow.com/questions/9692734/sql-server-nested-transactions-in-a-stored-procedure/9692880#9692880

推荐阅读
  • 本文详细介绍了Oracle RMAN中的增量备份机制,重点解析了差异增量和累积增量备份的概念及其在不同Oracle版本中的实现。通过对比两种备份方式的特点,帮助读者选择合适的备份策略。 ... [详细]
  • SQLite是一种轻量级的关系型数据库管理系统,尽管体积小巧,却能支持高达2TB的数据库容量,每个数据库以单个文件形式存储。本文将详细介绍SQLite在Android开发中的应用,包括其数据存储机制、事务处理方式及数据类型的动态特性。 ... [详细]
  • 本文详细介绍如何在Spring Boot项目中集成和使用JPA,涵盖JPA的基本概念、Spring Data JPA的功能以及具体的操作步骤,帮助开发者快速掌握这一强大的持久化技术。 ... [详细]
  • 视觉Transformer综述
    本文综述了视觉Transformer在计算机视觉领域的应用,从原始Transformer出发,详细介绍了其在图像分类、目标检测和图像分割等任务中的最新进展。文章不仅涵盖了基础的Transformer架构,还深入探讨了各类增强版Transformer模型的设计思路和技术细节。 ... [详细]
  • OBS Studio自动化实践:利用脚本批量生成录制场景
    本文探讨了如何利用OBS Studio进行高效录屏,并通过脚本实现场景的自动生成。适合对自动化办公感兴趣的读者。 ... [详细]
  • 本文详细探讨了在Web开发中常见的UTF-8编码问题及其解决方案,包括HTML页面、PHP脚本、MySQL数据库以及JavaScript和Flash应用中的乱码问题。 ... [详细]
  • 本文介绍了一种算法,用于在一个给定的二叉树中找到一个节点,该节点的子树包含最大数量的值小于该节点的节点。如果存在多个符合条件的节点,可以选择任意一个。 ... [详细]
  • 本文介绍了多种Eclipse插件,包括XML Schema Infoset Model (XSD)、Graphical Editing Framework (GEF)、Eclipse Modeling Framework (EMF)等,涵盖了从Web开发到图形界面编辑的多个方面。 ... [详细]
  • 本文介绍如何在SQL Server中利用WITH子句和窗口函数ROW_NUMBER()来查询每个类型下的最新数据行。示例包括表结构、数据插入以及最终的查询语句。 ... [详细]
  • 基于OpenCV的小型图像检索系统开发指南
    本文详细介绍了如何利用OpenCV构建一个高效的小型图像检索系统,涵盖从图像特征提取、视觉词汇表构建到图像数据库创建及在线检索的全过程。 ... [详细]
  • 探讨了生成时间敏感的一次性伪随机密码的方法,旨在通过加入时间因素防止重放攻击。 ... [详细]
  • 本文详细介绍了在 Windows 7 上安装和配置 PHP 5.4 的 Memcached 分布式缓存系统的方法,旨在减少数据库的频繁访问,提高应用程序的响应速度。 ... [详细]
  • 本文详细介绍了如何使用 Python 编程语言中的 Scapy 库执行 DNS 欺骗攻击,包括必要的软件安装、攻击流程及代码示例。 ... [详细]
  • 我在尝试将组合框转换为具有自动完成功能时遇到了一个问题,即页面上的列表框也被转换成了自动完成下拉框,而不是保持原有的多选列表框形式。 ... [详细]
  • 数据输入验证与控件绑定方法
    本文提供了多种数据输入验证函数及控件绑定方法的实现代码,包括电话号码、数字、传真、邮政编码、电子邮件和网址的验证,以及报表绑定和自动编号等功能。 ... [详细]
author-avatar
担路赢客免费建站
这个家伙很懒,什么也没留下!
Tags | 热门标签
RankList | 热门文章
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有