T-SQL 隐性模式下显性事务

本文探讨了T-SQL在隐性模式下如何处理显性事务,详细解释了在没有显性事务和有显性事务两种情况下的@@TRANCOUNT变化规则。在没有显性事务时,DML操作会将@@TRANCOUNT设为1并保持不变,直至COMMIT。而在有显性事务时,BEGIN TRAN会使@@TRANCOUNT变为2,以确保COMMIT前的正确性。通过示例代码展示了嵌套事务可能导致的隐式ROLLBACK情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

USE AdventureWorks2012
 GO
 SET IMPLICIT_TRANSACTIONS ON   
 GO
 PRINT 'Use explicit transactions with IMPLICIT_TRANSACTIONS ON'
 GO
 SELECT 'Tran count outside transaction'= @@TRANCOUNT     --@@TRANCOUNT为0
BEGIN TRAN   
SELECT 'Tran count in transaction'= @@TRANCOUNT       --@@TRANCOUNT一下子变为2,这是为何?不是应该只增加1个么?
COMMIT TRAN
 SELECT 'Tran count outside transaction'= @@TRANCOUNT  --@@TRANCOUNT为1
 GO
 COMMIT TRAN
 SET IMPLICIT_TRANSACTIONS OFF
 SELECT 'Tran count outside transaction'= @@TRANCOUNT  --@@TRANCOUNT为0
 GO


为什么@@TRANCOUNT 一下子变为2,而不是1呢?

乍一看,好像有点犯晕,糊涂啊。

其实, 要了解这个,需要知道隐性模式下两种事务类型,没有显性事务和有显性事务。

当 SET IMPLICT_TRANSATONS ON时,我们不知道究竟要执行那种类型,所以@@TRANCOUNT是0。

接下来,根据不同事务类型,@@TRANCOUNT不同:

1,没有显性事务

在这种情形,发生一个DML,@@TRANCOUNT变为1,以后无论发生多少DML,@@TRANCOUNT始终是1,因为事务已经打开,当执行COMMIT后,@@TRANCONT减为0。

很显然,这种类型不需要BEGIN TRAN。

2,有显性事务

在这种情形,需要保证最后的COMMIT前,@@TRANCOUNT大于0,否则会报错,没有与之匹配的BEGIN TRAN。一对显形事务的BEGIN TRAN和COMMIT执行不改变它前面和后面的@@TRANCOUNT,因此,要实现最后的COMMIT要求,第一个BEGIN TRAN是2,执行NESTED COMMIT,@@TRACONT为1,执行最后的COMMIT,@@TRANCOUNT为0。

 

最后,考虑一下下面的会发生什么:

BEGIN TRAN

DELETE1

BEGIN TRAN

DELETE2

BEGIN TRAN

DELETE2

COMMIT

 

 

呵呵,什么也不会发生,最外层这里隐含一个ROLLBACK。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值