MySQL' REPEATABLE READ'交易意外行为

时间:2017-03-08 09:59:00

标签: mysql sql transactions

MySQL事务的默认隔离级别是“可重复读取”。

根据另一个stackoverflow问题( Difference between read commit and repeatable read) "可重复读取是一个更高的隔离级别,除了保证读取提交级别之外,它还保证任何数据读取都不会改变,如果事务再次读取相同数据,它将找到先前读取的数据到位,不变,可供阅读。"

这是我的测试数据库;

overwrite

slow.sql

mysql> select * from people;
+------+---------+
| name | howmany |
+------+---------+
| alex |     100 |
| bob  |     100 |
+------+---------+

fast.sql

START TRANSACTION;

SELECT @new_val := howmany FROM people WHERE name = 'alex';
SELECT SLEEP(10);
SET @new_val = @new_val - 5;
UPDATE people SET howmany = @new_val WHERE name = 'alex';

COMMIT;

如果我运行slow.sql,在它返回之前我多次运行fast.sql。 fast.sql将打印95,90,85 ....

我认为可重复的读取隔离级别应该使fast.sql无法运行或者我误解了可重复读取的内容。

我从Ubuntu 16.10运行MySQL 5.7。

非常感谢。

3 个答案:

答案 0 :(得分:2)

如果没有错,那么Repeatable Read会讨论同一事务中的一致性读取而不是其他事务。来自MySQL Documentation

  
      
  • REPEATABLE READ
  •   
     

这是InnoDB的默认隔离级别。一致的读数   在同一个交易中读取第一个建立的快照   读。这意味着如果你发出几个普通(非锁定)SELECT   同一事务中的语句,这些SELECT语句都是   也是相互一致的。

答案 1 :(得分:1)

可重复读隔离级别可确保单个事务中的一致性。您正在执行多个交易。对于您期望的行为,您需要查看锁定读取。有关详细信息,请参见此处https://dev.mysql.com/doc/refman/5.7/en/innodb-transaction-isolation-levels.html#isolevel_repeatable-read

答案 2 :(得分:0)

如果某些数据在您的交易过程中发生变化,则不会对所述交易中的数据读取产生影响。

我不知道fast.sql因为这种隔离级别(或任何隔离)而无法运行。