postgresql - 如何在 PostgreSQL 中生成唯一的时间戳?

标签 postgresql race-condition vector-clock

我的想法是实现一个基本的“矢量时钟”,其中时间戳是基于时钟的,始终前进并保证是唯一的。

例如,在一个简单的表格中:

CREATE TABLE IF NOT EXISTS timestamps (
    last_modified TIMESTAMP UNIQUE
);

我使用触发器在插入之前设置时间戳值。当两个插入同时到达时,它基本上就会进入 future :

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();

然后我在两个单独的客户端中运行大量插入:

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 suggestedcurrent_clock()SEQUENCE 对象混合,但这可能意味着摆脱 TIMESTAMP 类型。尽管我无法真正弄清楚它如何解决隔离问题......

是否有通用模式可以避免这种情况?

感谢您的见解:)

最佳答案

我的两分钱(灵感来自http://tapoueh.org/blog/2013/03/15-batch-update)。

尝试在大量插入之前添加以下内容:

LOCK TABLE timestamps IN SHARE MODE;

官方文档在这里:http://www.postgresql.org/docs/current/static/sql-lock.html

关于postgresql - 如何在 PostgreSQL 中生成唯一的时间戳?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34817760/

相关文章:

node.js - 连接到 AWS RDS postgres 数据库的 nodejs 错误

postgresql - 临时列 "doesn' t 存在吗?”

postgresql - 如何更改 PostgreSQL 中的列默认值?

.net - 使用 BackgroundWorker.CancelAsync 时如何避免竞争条件?

在 K20 上没有 -G 选项时 CUDA C 返回不确定且奇怪的结果

c - fork() 和 pipeline() 的竞争条件

sql - 在 postgres 的 pg_dump 中节流 i/o?

mongodb - MongooseJS "versionKey"(__v 字段)是 "vector clock"吗?

distributed-computing - Messenger 如何在聊天期间和用户再次登录时保持消息的顺序?