【发布时间】:2018-02-21 15:30:33
【问题描述】:
根据https://www.postgresql.org/docs/9.5/static/sql-select.html
在 READ COMMITTED 运行 SELECT 命令是可能的 事务隔离级别并使用 ORDER BY 和锁定子句 乱序返回行。这是因为首先应用 ORDER BY。 该命令对结果进行排序,但随后可能会阻止尝试获取 锁定一个或多个行。一旦 SELECT 解除阻塞,一些 排序列值可能已被修改,导致这些行 似乎是无序的(尽管它们在 原始列值)。这可以通过放置在需要时解决 例如子查询中的 FOR UPDATE/SHARE 子句
SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss ORDER BY column1;请注意,这将导致锁定 mytable 的所有行,而 FOR 顶层的 UPDATE 只会锁定实际返回的行。 这可能会产生显着的性能差异,尤其是 如果 ORDER BY 与 LIMIT 或其他限制结合使用。所以这 仅当同时更新排序时才推荐使用该技术 列是预期的,并且需要严格排序的结果。在 REPEATABLE READ 或 SERIALIZABLE 事务隔离级别 这将导致序列化失败(SQLSTATE 为“40001”), 所以在这些条件下不可能接收到乱序的行 隔离级别。
假设我运行这个查询,
SELECT * FROM banks as x WHERE x.date < {inputDate} ORDER BY x.date DESC LIMIT 1 FOR UPDATE;
- 假设行日期不能修改
- 可以插入/删除银行行
- 无论比赛条件如何,我每次都能安全地获得正确的结果吗?
- 我检索到的单行会被 LOCK FOR UPDATE 吗? (我阅读了很多关于 LIMIT 和 FOR UPDATE 交互的资料,但仍然很困惑,有人可以确认这种情况下到底会发生什么吗?)
文章提到了错误的顺序,但我真的可以应用到我的用例中是否会在添加/删除时得到正确的结果。
【问题讨论】:
标签: sql postgresql