【问题标题】:Does encapsulating a statement in a transaction include the triggers it fires?在事务中封装语句是否包括它触发的触发器?
【发布时间】:2018-04-23 10:15:04
【问题描述】:

我有一个INSERT,它将触发一个TRIGGER,它将UPDATE 另一个TABLE 的属性。我需要确保如果INSERT 成功并且TRIGGER 中的UPDATE 不成功,那么整个事情应该回滚。

在事务中封装INSERT 能保证这一点吗?

如果没有,我该怎么做?

【问题讨论】:

  • 是的,应该。你为什么不试试呢?..
  • @VaoTsun 您通常如何强制触发器失败以进行测试?
  • 只是添加条件来更新?..例如update blah set blah where case when new.some_column = 4 then 1/0 else new.some_other_column end 因此,当您对 some_column = 4 的行进行操作时,它将异常死亡

标签: postgresql triggers transactions consistency


【解决方案1】:

触发器是包含原始INSERT的数据库事务的一部分。

事务中的任何错误(未处理)都会导致整个事务回滚,就像什么都没发生一样。这将包括导致触发器运行的INSERT

因此,您无需做任何事情;它会按照您想要的方式开箱即用。

您可以通过设置SAVEPOINTs 和使用ROLLBACK TO SAVEPOINT(或在PL/pgSQL 中使用BEGIN ... EXCEPTION ... END 块,这在后台执行相同的操作)来显式处理事务中的错误。

要触发异常,要么运行导致错误的 SQL 语句(如 SELECT 1/0),要么在 PL/pgSQL 中使用 RAISE EXCEPTION 语句(其他过程语言也有类似的方法)。

【讨论】:

  • 所以我什至不需要将插入放入事务中?
  • 对。每个语句都在一个事务中(默认情况下,每个语句都在它自己的事务中)。触发器在同一个事务中运行。数据库事务很酷,不是吗?
猜你喜欢
  • 2013-09-09
  • 2022-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多