如何保证top语句的PostgreSQL子语句之间的数据一致性?
我仍然无法弄清楚SQL语句是如何并行执行的,而不会影响彼此的工作。我大体上理解ACID原理,但在特殊情况下我很难理解它。例如,在下面的代码段中,如何保证top语句的PostgreSQL子语句之间的数据一致性?,postgresql,transactions,Postgresql,Transactions,我仍然无法弄清楚SQL语句是如何并行执行的,而不会影响彼此的工作。我大体上理解ACID原理,但在特殊情况下我很难理解它。例如,在下面的代码段中,bar.max_count的值是否不能反映执行更新时表foo中count的实际最大值?(例如,如果有人在表foo中的WITH语句和UPDATE语句之间更新或插入新行) 换句话说:此语句是否会“阻止”尝试在表foo中写入的其他并发语句 谢谢在更新mytable之前,并发语句可能会写入foo。但是,只要并发语句不从mytable中读取,一切都很好,因为这样就
bar.max_count
的值是否不能反映执行更新时表foo
中count
的实际最大值?(例如,如果有人在表foo
中的WITH
语句和UPDATE
语句之间更新或插入新行)
换句话说:此语句是否会“阻止”尝试在表foo
中写入的其他并发语句
谢谢在更新mytable
之前,并发语句可能会写入foo
。但是,只要并发语句不从mytable
中读取,一切都很好,因为这样就可以认为您的事务在逻辑上早于这些其他事务—就好像您的事务首先运行一样
但是,如果其中一个并发事务也从mytable
中读取了一个值,那么如果该信息被用于修改foo
,那么结果就不再需要一致,因为这样您就无法再对事务进行逻辑排序。这被称为事务异常,因为如果事务一个接一个地执行(序列化),它永远不会发生
如果在默认的readcommitted
隔离级别上操作,就会出现这种异常,该级别提供了较低级别的事务隔离
为了避免这种异常,您必须使用SERIALIZABLE
隔离级别,在该级别中,您可以保证始终具有可序列化的结果。但是,与可序列化的相关的性能成本是存在的,异常可以通过使用序列化错误终止其中一个相关事务来解决
另一种选择是悲观锁定,但在您的情况下,这会导致过度锁定。我将对您的帖子进行几次阅读。看来,毕竟,这不是一件容易的事。非常感谢。
WITH
bar AS (
SELECT id, MAX(count) AS max_count
FROM foo
GROUP BY id
)
UPDATE mytable
SET count = bar.max_count
FROM bar
WHERE mytable.id = bar.id