1

我要编写一个触发器来检查一些插入/更新的信息,将它们与数据库中的数据进行比较,如果它们不正确,则停止整个操作。我在触发器(每个)之前编写,然后如果出现问题,则抛出应用程序异常,但它不起作用,因为我从更新的表中读取,所以我得到 ORA-04091 错误。

现在我想知道如何解决这个问题?现在我唯一的想法是编写一个前触发器,将一些必要的数据插入到包中,并使用后触发器读取它们,这不是每个都适用的。但是有一个问题如何中止这个版本?如果我进行回滚,它将撤消此事务中我认为不明智的所有操作。你将如何解决这个问题?

4

1 回答 1

3

不要去那里。

ORA-04091: table XXXX is mutating通常是一个很好的指标,表明您尝试做的任何事情都太复杂而无法通过触发器可靠地完成。

当然,您可以使用包数组变量和一些触发器(啊!)来解决此错误,但您的代码很可能会:

  • 由于其复杂性和触发器的不可预测性而无法维护
  • 对多用户环境反应不佳

这就是为什么您在遇到此错误时应该重新考虑您的方法。我建议您构建一组很好地分组在一个包中的程序来处理行间一致性。撤销所有权限以直接对表进行 DML,并仅使用这些过程对其进行修改。

例如,您的更新过程将是一个原子过程,它将:

  1. 获取锁以防止对同一组行进行并发更新(例如锁定酒店预订应用程序中的房间记录)。
  2. 检查要插入的行是否验证所有业务逻辑
  3. 制作所有相关的 DML
  4. 在发生错误时回滚其所有更改(并且仅回滚其更改 - 而不是整个事务)(使用 PL/SQL 很容易,只需引发错误)。
于 2013-03-01T15:39:45.167 回答