在触发器中回滚和提交
在触发器中回滚和提交
当执行触发器时,触发器的操作好像有一个未完成的事务在起作用。不管激发触发器的语句在隐式事务中还是显式事务中,都会这样。
当语句开始以自动提交模式执行时,如果遇到错误,可以通过隐式 BEGIN TRANSACTION 语句恢复该语句生成的所有修改。此隐式事务对批处理中的其他语句没有影响,因为当语句完成时,此事务要么提交,要么回滚。但是,当调用触发器时,此隐式事务仍然有效。
执行触发器时,将开始隐式事务。如果触发器执行完后 @@TRANCOUNT 为 0,则会出现错误 3609 并终止批处理。由于这个原因,建议避免在触发器内部使用 ROLLBACK TRANSACTION(它将把 @@TRANCOUNT 重置为 0)以及 COMMIT TRANSACTION(它将把 @@TRANCOUNT 减少为 0)。在回滚后发出 BEGIN TRANSACTION 语句可以阻止错误的发生,但这样可能会导致应用程序逻辑出现问题。
了解在触发器中发出 BEGIN TRANSACTION 语句实际上是开始了一个嵌套事务这一点很重要。在这种情况下,执行 COMMIT TRANSACTION 语句将只应用到嵌套事务。因为回滚嵌套事务时将忽略嵌套的 BEGIN TRANSACTION 语句,所以触发器中执行的 ROLLBACK TRANSACTION 将回滚过去该触发器本身发出的所有 BEGIN TRANSACTION 语句。ROLLBACK 回滚到最外部事务并将 @@TRANCOUNT 设置为 0。
在触发器使用 ROLLBACK TRANSACTION 时,请注意下列行为:
- 当前事务中该时间点之前所做的所有数据修改都将回滚,包括触发器所做的修改。
- 触发器继续执行 ROLLBACK 语句之后的所有语句。如果这些语句中的任意语句修改数据,则不回滚这些修改。
- 触发器中的 ROLLBACK 关闭并释放所有在包含激发触发器的语句的批处理中声明和打开的游标。这包括在激发触发器的批处理所调用的存储过程中声明和打开的游标。在激发触发器的批处理之前的批处理中声明的游标只关闭。但是,STATIC 或 INSENSITIVE 游标在下列条件下不会关闭:
- CURSOR_CLOSE_ON_COMMIT 设置为 OFF。
- 静态游标是同步游标或者完全填充的异步游标。
可以不使用 ROLLBACK TRANSACTION,而使用 SAVE TRANSACTION 语句在触发器中执行部分回滚。
NOT FOR REPLICATION
定义一个插入触发器时设置了 NOT FOR REPLICATION 选项,则所有用户的插入操作都会触发该触发器,但复制代理的插入操作不会触发该触发器。
posted on 2013-09-05 09:50 YoungPop_Chen 阅读(3032) 评论(0) 编辑 收藏 举报