当前位置: 代码迷 >> SQL >> T-SQL 隐性模式上显性事务
  详细解决方案

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

热度:28   发布时间:2016-05-05 12:50:29.0
T-SQL 隐性模式下显性事务
USE AdventureWorks2012 GO SET IMPLICIT_TRANSACTIONS ON    GO PRINT 'Use explicit transactions with IMPLICIT_TRANSACTIONS ON' GO SELECT 'Tran count outside transaction'= @@TRANCOUNT     --@@TRANCOUNT为0BEGIN 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。

 

  相关解决方案