【问题标题】:Difference in Repeatable Read Semantics in MySQL and PostgreSQLMySQL 和 PostgreSQL 中可重复读语义的差异
【发布时间】:2018-11-15 14:51:26
【问题描述】:

我知道在MySQLPostgreSQL 中,REPEATABLE READ 隔离级别将使读取在事务开始时看到快照。但在https://dev.mysql.com/doc/refman/8.0/en/innodb-consistent-read.html 的 MySQL 文档中 下面的注释是用一个例子提到的

数据库状态的快照适用于其中的 SELECT 语句 一个事务,不一定是 DML 语句。如果您插入或 修改一些行,然后提交该事务,DELETE 或 UPDATE 从另一个并发 REPEATABLE READ 事务发出的语句 可能会影响那些刚刚提交的行,即使会话可能 不要查询他们。如果事务确实更新或删除已提交的行 通过不同的交易,这些更改确实对 当前交易。例如,您可能会遇到类似的情况 以下:

SELECT COUNT(c1) FROM t1 WHERE c1 = 'xyz';
-- Returns 0: no rows match.
DELETE FROM t1 WHERE c1 = 'xyz';
-- Deletes several rows recently committed by other transaction.

SELECT COUNT(c2) FROM t1 WHERE c2 = 'abc';
-- Returns 0: no rows match.
UPDATE t1 SET c2 = 'cba' WHERE c2 = 'abc';
-- Affects 10 rows: another txn just committed 10 rows with 'abc' values.
SELECT COUNT(c2) FROM t1 WHERE c2 = 'cba';
-- Returns 10: this txn can now see the rows it just updated.

同样的例子是否适用于 PostgreSQL,或者它不允许这样的行为?

【问题讨论】:

  • 很难给出一个普遍的答案是或否,最简单的方法是在两个数据库上测试各个场景并进行比较。困难在于可能有很多这样的场景,改变表中数据的三个基本命令:INSERT UPDATE DELETE,另外 SELECT FOR UPDATE 将 lok 放在行上,所有这些命令都可以以各种组合使用。行为也可能不同,具体取决于 AUTOCOMMIT 是打开还是关闭,以及是否使用 START TRANSACTION(BEGIN 命令)。这是一个很大的话题。
  • @krokodilko 回答“不”很容易。

标签: mysql sql postgresql transaction-isolation


【解决方案1】:

这在 PostgreSQL 中不会发生。

如果REPEATABLE READ 事务 A 在拍摄 A 的快照后尝试修改已被并发事务 B 修改的行,A 将收到“序列化错误”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-06
    • 2016-12-21
    • 2023-03-17
    • 1970-01-01
    • 2018-07-24
    • 2019-01-29
    • 2016-05-17
    相关资源
    最近更新 更多