SELECT 的 PostgreSQL 间隙锁 ... 更新
PostgreSQL Gap lock by SELECT ... FOR UPDATE
在 MySQL/InnoDB:
处使用了带有 Gap Lock 的查询
SELECT id, time, count
FROM table_a
WHERE time
BETWEEN DATE_SUB(NOW(), INTERVAL 24 HOUR)
AND NOW()
FOR UPDATE
它锁定 time
范围和 returns 最近的记录(如果存在)(过去 24 小时内)。
如果不是 - 会话在过去 24 小时内仍然拥有锁以安全地插入新记录。
在 PostgreSQL 中是否可以在整个 24 小时内(即使没有记录)进行相同的间隙锁定?
在 PostgreSQL 中做到这一点的方法是对所有事务使用 SERIALIZABLE
隔离级别。
那么您根本不需要 FOR UPDATE
。 PostgreSQL 不会阻止行被插入到间隙中,但是如果两个事务同时在同一个间隙中读取和写入值,其中一个将得到序列化错误并且必须重做事务(在第二次尝试时,它将发现间隙不为空)。
这里的工作概念是可串行化:如果其他人在没有读取的情况下插入间隙是可以接受的(该事务逻辑上在[=22=之后] 和你 SELECT
的那一个)。但是,如果两个事务都发现间隙为空,然后插入一些东西,那将产生一个被 SERIALIZABLE
.
阻止的异常
在 MySQL/InnoDB:
处使用了带有 Gap Lock 的查询SELECT id, time, count
FROM table_a
WHERE time
BETWEEN DATE_SUB(NOW(), INTERVAL 24 HOUR)
AND NOW()
FOR UPDATE
它锁定 time
范围和 returns 最近的记录(如果存在)(过去 24 小时内)。
如果不是 - 会话在过去 24 小时内仍然拥有锁以安全地插入新记录。
在 PostgreSQL 中是否可以在整个 24 小时内(即使没有记录)进行相同的间隙锁定?
在 PostgreSQL 中做到这一点的方法是对所有事务使用 SERIALIZABLE
隔离级别。
那么您根本不需要 FOR UPDATE
。 PostgreSQL 不会阻止行被插入到间隙中,但是如果两个事务同时在同一个间隙中读取和写入值,其中一个将得到序列化错误并且必须重做事务(在第二次尝试时,它将发现间隙不为空)。
这里的工作概念是可串行化:如果其他人在没有读取的情况下插入间隙是可以接受的(该事务逻辑上在[=22=之后] 和你 SELECT
的那一个)。但是,如果两个事务都发现间隙为空,然后插入一些东西,那将产生一个被 SERIALIZABLE
.