做一个INSERT内回滚后或触发更新后回滚整个交易(Does a rollback inside a

2019-07-30 09:55发布

做一个INSERT AFTER触发器或之后UPDATE内回滚回滚整个事务或只是当前行是触发的原因,是它一样具有提交?

我试图通过它使用MSTDC的交易我当前的项目代码,以检查它,它看起来好像虽然完整的交易被中止。

如果触发回滚不会回滚整个事务,是有限制它只是当前行的解决方法。

我发现了一个链接, SYBASE SQL Server上的这一点,但没有

Answer 1:

是的,它会回滚整个事务。

这一切都在文档 (见备注)。 请注意,我强调的评论 - 这是非常重要的,我会说!

如果ROLLBACK TRANSACTION在触发器中发出:

在当前的交易点所做的所有数据修改都将回滚,包括任何由触发器进行。

触发器继续执行 ROLLBACK语句之后剩余的语句 。 如果这些语句修改数据,该修改不会回滚。 没有嵌套触发器由这些剩余语句的执行解雇。

在批处理触发触发器的语句会后声明不会执行。



Answer 2:

正如你已经被我们知道,ROLLBACK命令不可能被修改/调整,使其只回滚由触发发表的声明。

如果你需要一种方式来“回滚”行动被触发执行而已,你可以,作为一种解决方法,可以考虑修改您的触发器以这样的方式,在进行操作之前,触发确保这些行动不会产生特殊情况是会导致整个事务回滚。

举例来说,如果你的触发器插入行,添加一个检查,以确保新行不违反例如,唯一约束(或外键约束),是这样的:

IF NOT EXISTS (
  SELECT *
  FROM TableA
  WHERE …  /* a condition to test if a row or rows you are about
              to insert aren't going to violate any constraint */
)
BEGIN
  INSERT INTO TableA …
END;

或者,如果你触发删除行,检查它是否没有试图删除其他表(在这种情况下,一般要事先知道哪些表可能会引用行)引用的行:

IF NOT EXISTS (
  SELECT * FROM TableB WHERE …
)
AND NOT EXISTS (
  SELECT * FROM TableC WHERE …
)
AND …
BEGIN
  DELETE FROM TableA WHERE …
END

同样,你需要为update语句检查,如果有的话。



Answer 3:

除非你指定一些保存点和你把回滚tran命令它不事关任何ROLLBACK命令将回滚一切,直到@@ TRANCOUNT为0。

最好的办法是寻找到代码再次确认的业务需求,看看你为什么需要在触发回退?



文章来源: Does a rollback inside a INSERT AFTER or UPDATE AFTER trigger rollback the entire transaction