1

我知道BEGIN TRAN@@trancount1COMMIT TRAN@@trancount1,但是UPDATE语句呢?它有什么影响,尤其是在隐式交易中?

我在https://docs.microsoft.com/en-us/sql/t-sql/functions/trancount-transact-sql?view=sql-server-2017上查找了信息, 但UPDATE从未提及该声明。

BEGIN TRY

    UPDATE cad
    SET [AccountExpirationDate] = DATEADD(MONTH, -13, [AccountExpirationDate])
    FROM [dbo].[CardActivationDetail] cad
    WHERE ci.[CardOrderId] = @CardOrderId;

END TRY
BEGIN CATCH
    IF @@trancount > 0
        ROLLBACK TRANSACTION;
END CATCH

在我发布的示例中,这是一个应用了开始/尝试捕获的隐式事务。@@Trancount在这种情况下如何工作?Update 语句是否将其增加 1 并且自动提交将其减少 1,离开@@trancount = 0

4

1 回答 1

2

[DML 语句] 对 [@@trancount] 有什么影响,尤其是在隐式事务中?

启用implicit_transactions 后,如果@@trancount = 0,则它会增加@@trancount 两次,运行并减1,运行任何后触发器,将其保留为1。

在implicit_transactions 关闭的情况下,如果@@trancount = 0,它会增加@@trancount 两次,运行并减一,运行任何AFTER 触发器,然后再次递减,提交。

在任何一种情况下,如果@@trancount > 0,那么它会将@@trancount 加1,运行,减1,运行任何AFTER 触发器。

您可以在死锁图中看到这种行为,也可以在 DML 中使用 @@trancount。

例如:

use tempdb
drop table if exists t
set nocount on
go
create table t(id int identity, a int)

go
create trigger tt on t after insert
as
begin
  select @@trancount trancount_in_trigger
end
go
set implicit_transactions off
go
if @@trancount > 0 rollback
go
print '---autocommit----'
select @@trancount trancount_before
insert into t(a) values (@@trancount)
select a trancount_during from t where id = SCOPE_IDENTITY()
select @@trancount trancount_after

go

begin transaction
print '---explicit transaction----'
select @@trancount trancount_before
insert into t(a) values (@@trancount)
select a trancount_during from t where id = SCOPE_IDENTITY()
select @@trancount trancount_after

commit

go

begin transaction
begin transaction
print '---explicit nested transaction----'
select @@trancount trancount_before
insert into t(a) values (@@trancount)
select a trancount_during from t where id = SCOPE_IDENTITY()
select @@trancount trancount_after

commit
commit

go 

set implicit_transactions on

go
print '---implicit transaction----'
select @@trancount trancount_before
insert into t(a) values (@@trancount)
select a trancount_during from t where id = SCOPE_IDENTITY()
select @@trancount trancount_after

commit

输出

---autocommit----
trancount_before
----------------
0

trancount_in_trigger
--------------------
1

trancount_during
----------------
2

trancount_after
---------------
0

---explicit transaction----
trancount_before
----------------
1

trancount_in_trigger
--------------------
1

trancount_during
----------------
2

trancount_after
---------------
1

---explicit nested transaction----
trancount_before
----------------
2

trancount_in_trigger
--------------------
2

trancount_during
----------------
3

trancount_after
---------------
2

---implicit transaction----
trancount_before
----------------
0

trancount_in_trigger
--------------------
1

trancount_during
----------------
2

trancount_after
---------------
1
于 2019-04-30T20:56:12.787 回答