You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
### <aid="nesting-transactions"></a> Outer and inner transactions
1770
1770
1771
-
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.
1771
+
An explicit inner transaction can be started within an explicit outer transaction. 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.
1772
1772
1773
-
The following example shows the use of nested transactions. If `TransProc` is called when a transaction is active, the outcome of the nested transaction in `TransProc` is controlled by the outer transaction, and its `INSERT` statements are committed or rolled back based on the commit or roll back of the outer transaction. If `TransProc` is executed by a process that doesn't have an outstanding transaction, the `COMMIT TRANSACTION` at the end of the procedure commits the `INSERT` statements.
1773
+
The following example shows the use of outer and inner transactions. If `TransProc` is called when a transaction is active, the outcome of the inner transaction in `TransProc` is controlled by the outer transaction, and its `INSERT` statements are committed or rolled back based on the commit or roll back of the outer transaction. If `TransProc` is executed by a process that doesn't have an outstanding transaction, the `COMMIT TRANSACTION` at the end of the procedure commits the `INSERT` statements.
1774
1774
1775
1775
```sql
1776
1776
SET QUOTED_IDENTIFIER OFF;
@@ -1805,7 +1805,7 @@ EXEC TransProc 1, 'aaa';
1805
1805
GO
1806
1806
1807
1807
/* Roll back the outer transaction, this will
1808
-
roll back TransProc's nested transaction. */
1808
+
roll back TransProc's inner transaction. */
1809
1809
ROLLBACK TRANSACTION OutOfProc;
1810
1810
GO
1811
1811
@@ -1824,13 +1824,16 @@ FROM TestTrans;
1824
1824
GO
1825
1825
```
1826
1826
1827
-
Committing inner transactions is ignored by the [!INCLUDE [Database Engine](../includes/ssde-md.md)] when an outer transaction is active. The transaction is either committed or rolled back based on the commit or roll back 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.
1827
+
Committing inner transactions is ignored by the [!INCLUDE [Database Engine](../includes/ssde-md.md)] when an outer transaction is active. The transaction is either committed or rolled back based on the commit or roll back at the end of the outermost transaction. If the outer transaction is committed, the inner 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.
1828
1828
1829
-
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_name` statement within a nested transaction refers to the transaction name of the outer transaction, the commit applies only to the innermost transaction.
1829
+
Each call to `COMMIT TRANSACTION` or `COMMIT WORK` applies to the last executed `BEGIN TRANSACTION`. If there are multiple `BEGIN TRANSACTION` statements, then a `COMMIT` statement applies only to the last statement, in other words to the innermost transaction. Even if a `COMMIT TRANSACTION transaction_name` statement within an inner transaction refers to the transaction name of the outer transaction, the commit applies only to the innermost transaction.
1830
1830
1831
-
It isn't allowed for the `transaction_name` parameter of a `ROLLBACK TRANSACTION` statement to refer to the inner transaction in 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.
1831
+
It isn't allowed for the `transaction_name` parameter of a `ROLLBACK TRANSACTION` statement to refer to the inner transaction in a set of named transactions. `transaction_name` can refer only to the transaction name of the outermost transaction.
1832
1832
1833
-
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 doesn't 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. To determine if you are already in a transaction, `SELECT @@TRANCOUNT` to see if it is 1 or more. If `@@TRANCOUNT` is 0, you are not in a transaction.
1833
+
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 doesn't have a transaction name rolls back the outer and all inner transactions and decrements `@@TRANCOUNT` to 0. Similarly, a `ROLLBACK TRANSACTION` that uses the transaction name of the outermost transaction rolls back the outer and all inner transactions and decrements `@@TRANCOUNT` to 0. To determine if you are already in a transaction, `SELECT @@TRANCOUNT` to see if it is 1 or more. If `@@TRANCOUNT` is 0, you are not in a transaction.
1834
+
1835
+
> [!NOTE]
1836
+
> The [!INCLUDE [ssde-md](../includes/ssde-md.md)] doesn't support independently manageable nested transactions. A commit of an inner transaction decrements `@@TRANCOUNT` but has no other effects. A rollback of an inner transaction always rolls back the outer transaction, unless a [savepoint](../t-sql/language-elements/save-transaction-transact-sql.md) exists and is specified in the `ROLLBACK` statement.
1834
1837
1835
1838
### <aid="using-bound-sessions"></a> Use bound sessions
Is a scalar function that reports the user transaction state of a current running request. XACT_STATE indicates whether the request has an active user transaction, and whether the transaction is capable of being committed.
Is a scalar function that reports the user transaction state of the current session. `XACT_STATE` indicates whether the session has an active user transaction, and whether the transaction is capable of being committed.
|1|The current request has an active user transaction. The request can perform any actions, including writing data and committing the transaction.|
51
-
|0|There is no active user transaction for the current request.|
52
-
|-1|The current request has an active user transaction, but an error has occurred that has caused the transaction to be classified as an uncommittable transaction. The request cannot commit the transaction or roll back to a savepoint; it can only request a full rollback of the transaction. The request cannot perform any write operations until it rolls back the transaction. The request can only perform read operations until it rolls back the transaction. After the transaction has been rolled back, the request can perform both read and write operations and can begin a new transaction.<br /><br /> When the outermost batch finishes running, the [!INCLUDE[ssDE](../../includes/ssde-md.md)] will automatically roll back any active uncommittable transactions. If no error message was sent when the transaction entered an uncommittable state, when the batch finishes, an error message will be sent to the client application. This message indicates that an uncommittable transaction was detected and rolled back.|
53
-
54
-
Both the XACT_STATE and @@TRANCOUNT functions can be used to detect whether the current request has an active user transaction. @@TRANCOUNT cannot be used to determine whether that transaction has been classified as an uncommittable transaction. XACT_STATE cannot be used to determine whether there are nested transactions.
55
-
56
-
## Examples
57
-
The following example uses `XACT_STATE` in the `CATCH` block of a `TRY...CATCH` construct to determine whether to commit or roll back a transaction. Because `SET XACT_ABORT` is `ON`, the constraint violation error causes the transaction to enter an uncommittable state.
58
-
59
-
```sql
60
-
USE AdventureWorks2022;
61
-
GO
62
-
63
-
-- SET XACT_ABORT ON will render the transaction uncommittable
64
-
-- when the constraint violation occurs.
65
-
SET XACT_ABORT ON;
66
-
67
-
BEGIN TRY
68
-
BEGIN TRANSACTION;
69
-
-- A FOREIGN KEY constraint exists on this table. This
70
-
-- statement will generate a constraint violation error.
71
-
DELETEFROMProduction.Product
72
-
WHERE ProductID =980;
73
-
74
-
-- If the delete operation succeeds, commit the transaction. The CATCH
75
-
-- block will not execute.
76
-
COMMIT TRANSACTION;
77
-
END TRY
78
-
BEGIN CATCH
79
-
-- Test XACT_STATE for 0, 1, or -1.
80
-
-- If 1, the transaction is committable.
81
-
-- If -1, the transaction is uncommittable and should
82
-
-- be rolled back.
83
-
-- XACT_STATE = 0 means there is no transaction and
84
-
-- a commit or rollback operation would generate an error.
85
-
86
-
-- Test whether the transaction is uncommittable.
87
-
IF (XACT_STATE()) =-1
88
-
BEGIN
89
-
PRINT 'The transaction is in an uncommittable state.'+
90
-
' Rolling back transaction.'
91
-
ROLLBACK TRANSACTION;
92
-
END;
93
-
94
-
-- Test whether the transaction is active and valid.
| 1 | The current session has an active user transaction. The session can perform any actions, including writing data and committing the transaction. |
56
+
| 0 | There's no active user transaction for the current session. |
57
+
| -1 | The current session has an active user transaction, but an error occurred that caused the transaction to be classified as an uncommittable transaction. The session can't commit the transaction or roll back to a savepoint; it can only request a full rollback of the transaction. The session can't perform any write operations until it rolls back the transaction. The session can only perform read operations until it rolls back the transaction. After the transaction is rolled back, the session can perform both read and write operations and can begin a new transaction.<br /><br />When the outermost batch finishes running, the [!INCLUDE [ssDE](../../includes/ssde-md.md)] automatically rolls back any active uncommittable transactions. If no error message was sent when the transaction entered an uncommittable state, when the batch finishes, an error message is sent to the client application. This message indicates that an uncommittable transaction was detected and rolled back. |
58
+
59
+
Both the `XACT_STATE` and `@@TRANCOUNT` functions can be used to detect whether the current session has an active user transaction. `@@TRANCOUNT` can't be used to determine whether that transaction is classified as an uncommittable transaction. `XACT_STATE` can't be used to determine whether there are inner transactions.
The following example uses `XACT_STATE` in the `CATCH` block of a `TRY...CATCH` construct to determine whether to commit or roll back a transaction. Because `SET XACT_ABORT` is `ON`, the constraint violation error causes the transaction to enter an uncommittable state.
66
+
67
+
```sql
68
+
-- SET XACT_ABORT ON renders the transaction uncommittable
69
+
-- when the constraint violation occurs.
70
+
SET XACT_ABORT ON;
71
+
72
+
BEGIN TRY
73
+
BEGIN TRANSACTION;
74
+
-- A FOREIGN KEY constraint exists on this table. This
75
+
-- statement generates a constraint violation error.
76
+
DELETEFROMProduction.Product
77
+
WHERE ProductID =980;
78
+
79
+
-- If the delete operation succeeds, commit the transaction. The CATCH
0 commit comments