chekur13 wrote:Разбирались с одной задачкой из теста и обнаружили странное поведение двух, казалось бы одинаковых кусков кода
Code: Select all
begin transaction mytran2
select @@trancount
begin transaction mytran1
select @@trancount
rollback transaction mytran1
select @@trancount
commit transaction mytran2
select @@trancount
rollback
В этом случае возникает ошибка, остается брошенной транзакция, на мой взгляд поведение ожидаемое (не учитывая брошенную транзакцию)
Code: Select all
Server: Msg 6401, Level 16, State 1, Line 10
Cannot roll back mytran1. No transaction or savepoint of that name was found.
Тот же кусок кода, только изменено имя mytran2 на mytran
Code: Select all
begin transaction mytran
select @@trancount
begin transaction mytran1
select @@trancount
rollback transaction mytran1
select @@trancount
commit transaction mytran
select @@trancount
Ошибка уже другая
Code: Select all
Server: Msg 3902, Level 16, State 1, Line 14
The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.
Кто-нибудь может прокомментировать подобное поведение???
Sometimes it's useful to read the manual:
"Committing inner transactions is ignored by Microsoft® SQL Server™.
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_name statement 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 the nested transactions are rolled back.
"
and
""Naming multiple transactions in a series of nested transactions with a transaction name has little effect on the transaction. Only the first (outermost) transaction name is registered with the system. A rollback to any other name (other than a valid savepoint name) generates an error. None of the statements executed before the rollback are in fact rolled back at the time this error occurs. The statements are rolled back only when the outer transaction is rolled back.
"
VC