私の考えは、タイムスタンプがクロックベースであり、常に前進し、一意であることが保証されている基本的な «vector clock» を実装することです。
たとえば、単純なテーブルでは次のようになります。
CREATE TABLE IF NOT EXISTS timestamps (
last_modified TIMESTAMP UNIQUE
);
トリガーを使用して、挿入前にタイムスタンプ値を設定します。基本的に、2 つの挿入が同時に到着すると、未来に進みます。
CREATE OR REPLACE FUNCTION bump_timestamp()
RETURNS trigger AS $$
DECLARE
previous TIMESTAMP;
current TIMESTAMP;
BEGIN
previous := NULL;
SELECT last_modified INTO previous
FROM timestamps
ORDER BY last_modified DESC LIMIT 1;
current := clock_timestamp();
IF previous IS NOT NULL AND previous >= current THEN
current := previous + INTERVAL '1 milliseconds';
END IF;
NEW.last_modified := current;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS tgr_timestamps_last_modified ON timestamps;
CREATE TRIGGER tgr_timestamps_last_modified
BEFORE INSERT OR UPDATE ON timestamps
FOR EACH ROW EXECUTE PROCEDURE bump_timestamp();
次に、2 つの別々のクライアントで大量の挿入を実行します。
DO
$$
BEGIN
FOR i IN 1..100000 LOOP
INSERT INTO timestamps DEFAULT VALUES;
END LOOP;
END;
$$;
予想どおり、衝突が発生します。
ERROR: duplicate key value violates unique constraint "timestamps_last_modified_key"
État SQL :23505
Détail :Key (last_modified)=(2016-01-15 18:35:22.550367) already exists.
Contexte : SQL statement "INSERT INTO timestamps DEFAULT VALUES"
PL/pgSQL function inline_code_block line 4 at SQL statement
@rach はオブジェクトと混合current_clock()
することを提案しましたSEQUENCE
が、それはおそらくTIMESTAMP
型を取り除くことを意味します。分離の問題をどのように解決するかはわかりませんが...
これを回避する一般的なパターンはありますか?
あなたの洞察をありがとう:)