
从上边的测试情况,看出,Update Contact触发tr_Contact触发器操作,触发器里面的Rollback Tran 动作导致了触发器外面的Update语句执行回滚,而Rollback Tran 语句后面的Begin Tran语句,主要是应用于保持整个事务的完整性。为了更能理解这一过程,我模拟了一个触发器中的事务开始结束过程。

图4.
在SQL Server 2005 和 SQL Server 2008上面,可以看到如图4.的效果。在低版本的SQL Server上,可能会出现错误提示情况,不管如何,在触发器外面,SQL Server都会Rollback Tran。下面我做个错误提示的例子。
修改触发器tr_Contact内容
use tempdb
Go
If Exists(Select 1 From sys.triggers Where name=’tr_Contact’)
Drop Trigger tr_Contact
Go
Create Trigger tr_Contact On Contact After Update,Delete
As
Insert Into ContactHIST(ContactID,Name,Sex)
Select ID,Name,Sex From deleted
Rollback Tran
–Begin Tran
Go
重新执行Update操作,
use tempdb
Go
Update Contact
Set Sex=’M’
Where Name=’Bill’
Go
Select @@TRANCOUNT
Go
Select * From Contact
Select * From ContactHIST
Go


在触发器里面没有Begin Tran语句动作,触发器外面也能回滚操作。这里我们可以通过查询表数据和@@Trancount来判断。
其实,上面的例子,Update语句,是以自动提交事务(Autocommit Transactions)模式 开始执行的,触发器里Rollback Tran后面,不管有没有Begin Tran ,最后都会事务都会交回给SQL Server自动提交事务管理。当然,在DML触发器中,你可以使用显式事务(Explicit Transactions),或开启隐式事务(Implicit Transactions) 来控制,当然你也可以应用于批范围的事务(Batch-scoped Transactions) 中。这里,我通过开启隐式事务(Implicit Transactions) 的例子来说,触发器与事务的关系。
修改触发器tr_Contact的内容,
use tempdb
Go
If Exists(Select 1 From sys.triggers Where name=’tr_Contact’)
Drop Trigger tr_Contact
Go
Create Trigger tr_Contact On Contact After Update,Delete










