博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Nested transactions in stored procedure of SQLServer
阅读量:5897 次
发布时间:2019-06-19

本文共 5724 字,大约阅读时间需要 19 分钟。

question:

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

Lets demo this using below code.

create procedure sp1BEGIN BEGIN TRANSACTION...exec sp2COMMIT 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 BITASBEGIN    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;ENDGO

 

Inner proc:

CREATE PROCEDURE dbo.sp2    @trip BITASBEGIN    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;ENDGO

 

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;GOSET NOCOUNT OFF;GOUSE AdventureWorks2008R2;GOCREATE TABLE TestTrans(Cola INT PRIMARY KEY,               Colb CHAR(3) NOT NULL);GOCREATE PROCEDURE TransProc @PriKey INT, @CharCol CHAR(3) ASBEGIN TRANSACTION InProcINSERT 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;GOEXEC TransProc 1, 'aaa';GO/* Roll back the outer transaction, this will   roll back TransProc's nested transaction. */ROLLBACK TRANSACTION OutOfProc;GOEXECUTE 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
 
整理自
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

转载地址:http://gdxsx.baihongyu.com/

你可能感兴趣的文章
酷客多小程序会员体系上线,你不可不知道!
查看>>
objective c:import和include的区别, ""和<>区别
查看>>
CentOS 6.5上部署drbd
查看>>
spring SchedulerFactoryBean 没有创建 Scheduler的实现类bea
查看>>
基于cobbler实现自动化安装系统
查看>>
java基础专栏—IOUtils(4)
查看>>
TimeUnit使用
查看>>
进程管理
查看>>
我的VIM配置(ubuntu)
查看>>
linux 常用配置文件
查看>>
cisco交换机配置练习疑难
查看>>
我的友情链接
查看>>
16、MariaDB工作中遇到的一部分报错的解决方法
查看>>
jdk的fastdebug版本是什么
查看>>
ConcurrentLinkedQueue cas实现分析
查看>>
在论坛中出现的比较难的sql问题:13(循环替换问题)
查看>>
简单的Samba服务器安装
查看>>
blog addr
查看>>
如何选择 Web 前端模板引擎?
查看>>
VMware 上Clone Ubuntu虚拟机后找不到eth0
查看>>