Bootstrap

mysql事务隔离级别幻读_MySQL事务隔离级别为"REPEATABLE-READ"下的"幻读"现象

MySQL事务隔离级别为"REPEATABLE-READ"下的"幻读"现象

mysql中的可重复读

这里打开两个mysql的命令行窗口,窗口A,即session1,窗口B,即session2。

session1

mysql> begin ;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from t1;

+----+------+

| a  | b    |

+----+------+

| 51 | 3000 |

| 52 | 3000 |

| 53 | 3000 |

| 54 | 3000 |

+----+------+

4 rows in set (0.00 sec)

session2

mysql> begin ;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into t1 values (55, 3000);

Query OK, 1 row affected (0.00 sec)

mysql> commit;

Query OK, 0 rows affected (0.03 sec)

mysql> select * from t1;

+----+------+

| a  | b    |

+----+------+

| 51 | 3000 |

| 52 | 3000 |

| 53 | 3000 |

| 54 | 3000 |

| 55 | 3000 |

+----+------+

5 rows in set (0.00 sec)

session2事务已经显示提交

session1

此时返回session1进行以下操作

mysql> select * from t1;

+----+------+

| a  | b    |

+----+------+

| 51 | 3000 |

| 52 | 3000 |

| 53 | 3000 |

| 54 | 3000 |

+----+------+

4 rows in set (0.00 sec)

此时,虽然在session2中插入了一条数据,并且提交了事务,但在session1中的查询和session1的上次查询还是同一个结果,这就是重复读。如果是在"READ-COMMITTED"级别下是可以读到a=55这条记录的。

测试mysql可重复读(二)

session1

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from t1 where a = 56;

+----+------+

| a  | b    |

+----+------+

| 56 | 7000 |

+----+------+

1 row in set (0.00 sec)

session2

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> update t1 set b = 8000 where a = 56;

Query OK, 1 row affected (0.00 sec)

Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from t1 where a = 56;

+----+------+

| a  | b    |

+----+------+

| 56 | 8000 |

+----+------+

1 row in set (0.00 sec)

mysql> commit

-> ;

Query OK, 0 rows affected (0.04 sec)

session1

mysql> select * from t1 where a = 56;

+----+------+

| a  | b    |

+----+------+

| 56 | 7000 |

+----+------+

1 row in set (0.00 sec)

和上次查询结果一致,验证了重复读。。。

此时,如果session1提交该事务,重新开启事务,查询能查到session2中修改的结果

mysql> commit;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from t1 where a = 56;

+----+------+

| a  | b    |

+----+------+

| 56 | 8000 |

+----+------+

1 row in set (0.00 sec)

REPEATABLE-READ下的幻读

session1

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from t1;

+----+------+

| a  | b    |

+----+------+

| 51 | 3000 |

| 52 | 3000 |

| 53 | 3000 |

| 54 | 3000 |

| 55 | 4000 |

| 56 | 8000 |

+----+------+

6 rows in set (0.00 sec)

session2

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from t1;

+----+------+

| a  | b    |

+----+------+

| 51 | 3000 |

| 52 | 3000 |

| 53 | 3000 |

| 54 | 3000 |

| 55 | 4000 |

| 56 | 8000 |

+----+------+

6 rows in set (0.00 sec)

mysql> insert into t1 values (57, 1000);

Query OK, 1 row affected (0.00 sec)

mysql> select * from t1;

+----+------+

| a  | b    |

+----+------+

| 51 | 3000 |

| 52 | 3000 |

| 53 | 3000 |

| 54 | 3000 |

| 55 | 4000 |

| 56 | 8000 |

| 57 | 1000 |

+----+------+

7 rows in set (0.00 sec)

mysql> commit;

Query OK, 0 rows affected (0.11 sec)

session1

mysql> update t1 set b = b+1000;

Query OK, 7 rows affected (0.00 sec)

Rows matched: 7  Changed: 7  Warnings: 0

mysql> select * from t1;

+----+------+

| a  | b    |

+----+------+

| 51 | 4000 |

| 52 | 4000 |

| 53 | 4000 |

| 54 | 4000 |

| 55 | 5000 |

| 56 | 9000 |

| 57 | 2000 |

+----+------+

7 rows in set (0.00 sec)

session1整个会话的sql

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from t1;

+----+------+

| a  | b    |

+----+------+

| 51 | 3000 |

| 52 | 3000 |

| 53 | 3000 |

| 54 | 3000 |

| 55 | 4000 |

| 56 | 8000 |

+----+------+

6 rows in set (0.00 sec)

mysql> select * from t1;

+----+------+

| a  | b    |

+----+------+

| 51 | 3000 |

| 52 | 3000 |

| 53 | 3000 |

| 54 | 3000 |

| 55 | 4000 |

| 56 | 8000 |

+----+------+

6 rows in set (0.00 sec)

mysql> update t1 set b = b+1000;

Query OK, 7 rows affected (0.00 sec)

Rows matched: 7  Changed: 7  Warnings: 0

mysql> select * from t1;

+----+------+

| a  | b    |

+----+------+

| 51 | 4000 |

| 52 | 4000 |

| 53 | 4000 |

| 54 | 4000 |

| 55 | 5000 |

| 56 | 9000 |

| 57 | 2000 |

+----+------+

7 rows in set (0.00 sec)

mysql>

可以看到多出了一行,这就是幻读。。。

但有一个问题,还是不明白,幻读和不可重复读到底什么区别?网上查了很多资料还是说的不明白,希望有了解的同学可以交流一下啊。。。

=====END====

原文:http://my.oschina.net/xinxingegeya/blog/296513

;