私たちのアプリケーション (内部の PostgreSQL (現在は 9.1、9.2 に移行中) を使用) では、リクエストの処理中に特定の行を INSERT (または UPDATE) および UPDATE します。したがって、次のようになります。
BEGIN
INSERT(pg), UPDATE(java)
XOR
UPDATE(pg), UPDATE(java)
COMMIT
(処理は postgres と Java の間で分割され、postgres は可能なもの (他の列は NULL) を取得および挿入/更新し、コントロールを Java アプリに戻し、残りの列を更新します)。
悲しいことに、特定の行でのコミット後にデータの一貫性が失われる可能性があるアプリケーションの設計上の欠陥を発見しました (非常にまれな状況で、何年にもわたって 1 回だけ発生していました)。具体的には、columnA = 'someConstant' の場合、commit の後、columnB を NULL にすることはできません (ただし、最初の挿入/更新の後、2 回目の更新の前にすることはできます!)。
アプリケーションを再設計する際に、これが発生しないようにするための短期間の回避策を提供する必要があります。
私は現在、いわゆる CONSTRAINT TRIGGER で遊んでいます。COMMIT の直前に DEFERRED にすることができ、任意のチェックと RAISE EXCEPTION を実行できます (トランザクションが正常にロールバックされるため、これは適切です)。問題は、(INSERT,UPDATE) または (UPDATE,UPDATE) ステートメントがあることです。私が言ったように、前述の一貫性のない列は途中で有効ですが、トランザクションの最後に有効です。これが秘訣です: トリガーは 2 番目のステートメントに対してのみ起動する必要があります。FOR EACH ROW と FOR EACH STATEMENT が見つかりました。どちらも 2 回起動するため、これは役に立ちませんが、2 番目の UPDATE ステートメントでのみ起動する必要があります。
何か案は?