Nested transactions in stored procedure of SQLServer
2014-04-16 21:43
302 查看
question:
if the nested transaction encountered an exception, then rollbacked. How about the outer transaction?
Lets demo this using below code.
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
Outer proc:
Inner proc:
So now let's call it and let everything commit:
Results:
1
2
1
1
0
Now let's call it and roll back the inner procedure:
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.
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
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
@@TRANCOUNTincrease 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
相关文章推荐
- Microsoft SQL Server 2005 Stored Procedure Programming in T-SQL & .NET
- [转载]:How to pass a list of values or array to SQL Server stored procedure?
- Dejan Sunderic, «Microsoft SQL Server 2005 Stored Procedure Programming in T-SQL & .NET» (3rd edition)
- HOW TO: Change the Owner of a User-Defined Data Type That Is in Use in SQL Server 2000
- filegroup reference and partitioning scheme' is not supported in this version of sql server.
- how to debug store procedure in sql server 2005
- Lock pages in memory now available for 64 bit Standard Edition of SQL Server
- SQL Interview Preparation (in the context of MS SQL Server)
- 转载:Character data is represented incorrectly when the code page of the client computer differs from the code page of the database in SQL Server 2005
- A SQL Server DBA myth a day: (26/30) nested transactions are real
- To SP or not to SP in SQL Server: an argument for stored procedures
- Using INSTEAD OF triggers in SQL Server for DML operations
- Do not include the "@" character when supplying stored procedure parameter names to a SQL Server database
- Error: The version of SQL Server in use does not support datatype 'datetime2
- Database cannot be started in this edition of SQL Server" error when restoring a Microsoft Dynamics CRM database
- 视图 调用 存储过程 view call procedure in sqlserver 2008
- nested exception is java.sql.SQLException: Unknown type '246 in column 1 of 3 in binary-encoded result set. 问题
- Failed to generate a user instance of SQL Server due to a failure in starting the process for the user instance
- Description of the SQL Server Agent jobs in BizTalk Server
- SQL Server Autogrow of file ‘xxx_Log’ in database ‘xxx’ was cancelled by user or timed out解决方法