【发布时间】:2021-04-16 22:57:44
【问题描述】:
我读过创建for insert trigger 会隐式创建事务。所以我可以从触发器中回滚事务并“撤消”插入。
是这样吗?
create trigger TRIGGER_NAME
on TABLE_NAME
for insert
as
declare @someVar = ....
if @someVar > 0
begin
rollback transaction
end
那么在那种情况下,如果@someVar大于0,insert就会被取消,对吧?
create trigger TRIGGER_NAME
on TABLE_NAME
for insert
as
begin transaction
declare @someVar = ....
if @someVar > 0
begin
rollback transaction
end
commit transaction
这样的话insert也会被取消吧?
当我们有两个for insert trigger 用于同一个表时会发生什么,并且他们都做rollback transaction 他们共享同一个隐式事务吗?
我在这件事上遇到了一些复杂情况,因此我尝试在每个触发器中创建自己的显式事务,但是对于 begin transaction,我无法正确使用 inserted,我无法提取任何值来自它。
【问题讨论】:
-
不要在触发器中创建自己的事务!!!!永远不会......触发器在导致它触发的语句 (
INSERT) 的上下文中运行(和事务)。是的 - 如果您检查某些条件并想中止,您可以执行ROLLBACK并取消该交易。但永远不要在触发器中创建自己的“子事务”! -
@marc_s 好的。有什么办法可以将交易嵌套在一起吗?当我在函数中调用函数时(例如将记录插入表的过程,它调用插入触发器。过程和触发器都使用事务。在触发器中回滚一直回滚到第一个事务,这不是我想要的)
-
否 - SQL Server 具有用于嵌套事务的 语法 - 不幸的是,它缺少适当的功能。如果您在嵌套事务中回滚,则该回滚会影响所有事务,一直到最外层
-
@marc_s 所以不可能按照我想要的方式嵌套事务?我无能为力,对吧?
-
这是正确的 - SQL Server 当前不支持嵌套/独立事务。您的触发器始终在导致其触发的 SQL 语句的事务的上下文中执行 - 并且您只能在需要时回滚该事务(因此取消 all 插入 - 您无法区分行) - 不能比这更具体/详细....
标签: sql sql-server triggers transactions insertion