次のトリガーを作成して、挿入のフィールド 'filesequence' が 1 人の利害関係者に対して常に最大値 + 1 を受け取ることを保証しました。
CREATE OR REPLACE FUNCTION update_filesequence()
RETURNS TRIGGER AS '
DECLARE
lastSequence file.filesequence%TYPE;
BEGIN
IF (NEW.filesequence IS NULL) THEN
PERFORM ''SELECT id FROM stakeholder WHERE id = NEW.stakeholder FOR UPDATE'';
SELECT max(filesequence) INTO lastSequence FROM file WHERE stakeholder = NEW.stakeholder;
IF (lastSequence IS NULL) THEN
lastSequence = 0;
END IF;
lastSequence = lastSequence + 1;
NEW.filesequence = lastSequence;
END IF;
RETURN NEW;
END;
' LANGUAGE 'plpgsql';
CREATE TRIGGER file_update_filesequence BEFORE INSERT
ON file FOR EACH ROW EXECUTE PROCEDURE
update_filesequence();
しかし、データベースで「filesequence」を繰り返しました:
select id, filesequence, stakeholder from file where stakeholder=5273;
id filesequence stakeholder
6773 5 5273
6774 5 5273
私の理解では、SELECT... FOR UPDATE は同じ利害関係者の 2 つのトランザクションをロックし、2 番目のトランザクションは新しい「ファイルシーケンス」を読み取ります。しかし、それは機能していません。
PgAdmin でいくつかのテストを行い、以下を実行しました。
BEGIN;
select id from stakeholder where id = 5273 FOR UPDATE;
そして、同じ利害関係者に挿入されている他のレコードを実際にロックしました。するとLOCKが効いているようです。
しかし、同時アップロードでアプリケーションを実行すると、繰り返し表示されます。
誰かが私のトリガーの問題を見つけるのを手伝ってくれますか?
ありがとう、ダグラス。