在我们的应用程序中(使用 PostgreSQL 引擎盖(目前是 9.1,移动到 9.2)我们在处理某些请求时再次插入(或更新)和更新特定行。所以它看起来像:
BEGIN
INSERT(pg), UPDATE(java)
XOR
UPDATE(pg), UPDATE(java)
COMMIT
(进程在 postgres 和 java 之间划分,postgres 获取并插入/更新它可以的内容(其他列 NULL),将控制权返回给 java 应用程序,并更新剩余的列)。
遗憾的是,我们在应用程序中发现了一个设计缺陷,该缺陷可能会导致特定行中的提交后数据不一致(在极其罕见的情况下,多年来一直发生这种情况)。更具体地说,如果 columnA = 'someConstant',则在 COMMIT 之后 columnB 不能为 NULL(但它可以在第一次插入/更新之后和第二次更新之前!)。
在重新设计应用程序时,我们必须提供一些短期解决方法来防止这种情况发生。
我目前正在玩所谓的约束触发器。它们可以在 COMMIT 之前被 DEFERRED,它们可以进行任意检查和 RAISE EXCEPTION(这很好,因为事务将正常回滚)。问题是我有 (INSERT,UPDATE) 或 (UPDATE,UPDATE) 语句。正如我所说,提到的不一致列在中间有效,但在事务结束时。所以这就是诀窍:触发器应该只为第二条语句触发。我正在挖掘文档,发现 FOR EACH ROW 和 FOR EACH STATEMENT。这无济于事,因为它们都会触发两次,但我必须只触发第二个 UPDATE 语句。
有任何想法吗?