session B:
mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> update tb_book set book_name = '多情刀客无情刀' where book_id = 1; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> rollback; Query OK, 0 rows affected (0.00 sec)结果:事务A读到了事务B还没提交的中间状态,即产生了脏读。
不可重复读(read committed)事务A读到了事务B已经提交的修改数据
操作:
session A事务隔离级别设置为read committed并开启事务,首次查询book_id为1的记录;
然后session B开启事务,并修改book_id为1的记录,不提交事务,在session A中再次查询book_id为1的记录;
最后提交session B中的事务,再在session A中查看book_id为1的记录。
session A:
mysql> set session transaction isolation level read committed; Query OK, 0 rows affected (0.01 sec) mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> select * from tb_book where book_id = 1; +---------+-----------------------+--------+ | book_id | book_name | author | +---------+-----------------------+--------+ | 1 | 多情剑客无情剑 | 古龙 | +---------+-----------------------+--------+ 1 row in set (0.00 sec) mysql> select * from tb_book where book_id = 1; +---------+-----------------------+--------+ | book_id | book_name | author | +---------+-----------------------+--------+ | 1 | 多情剑客无情剑 | 古龙 | +---------+-----------------------+--------+ 1 row in set (0.00 sec) mysql> select * from tb_book where book_id = 1; +---------+-----------------------+--------+ | book_id | book_name | author | +---------+-----------------------+--------+ | 1 | 多情刀客无情刀 | 古龙 | +---------+-----------------------+--------+ 1 row in set (0.00 sec) mysql> commit; Query OK, 0 rows affected (0.00 sec)session B:
mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> update tb_book set book_name = '多情刀客无情刀' where book_id = 1; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> commit; Query OK, 0 rows affected (0.00 sec)结果:事务B没有提交事务时,事务A不会读到事务B修改的中间状态,即read committed解决了上面所说的脏读问题,但是当事务B中的事务提交后,事务A读到了修改后的记录,而对于事务A来说,仅仅读了两次,却读到了两个不同的结果,违背了事务之间的隔离性,所以说该事务隔离级别下产生了不可重复读的问题。
幻读(repeatable read)事务A读到了事务B提交的新增数据
操作:
session A事务隔离级别设置为repeatable read并开启事务,并查询book列表
session B开启事务,先修改book_id为5的记录,再插入一条新的数据,提交事务,在session A中再次查询book列表
在session A中更新session B中新插入的那条数据,再查询book列表
session A:
mysql> set session transaction isolation level repeatable read; Query OK, 0 rows affected (0.00 sec) mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> select * from tb_book; +---------+-----------------------+--------+ | book_id | book_name | author | +---------+-----------------------+--------+ | 1 | 多情刀客无情刀 | 古龙 | | 2 | 笑傲江湖 | 金庸 | | 3 | 倚天屠龙记 | 金庸 | | 4 | 射雕英雄传 | 金庸 | | 5 | 绝代双骄 | 古龙 | +---------+-----------------------+--------+ 5 rows in set (0.00 sec) mysql> select * from tb_book; +---------+-----------------------+--------+ | book_id | book_name | author | +---------+-----------------------+--------+ | 1 | 多情刀客无情刀 | 古龙 | | 2 | 笑傲江湖 | 金庸 | | 3 | 倚天屠龙记 | 金庸 | | 4 | 射雕英雄传 | 金庸 | | 5 | 绝代双骄 | 古龙 | +---------+-----------------------+--------+ 5 rows in set (0.00 sec) mysql> update tb_book set book_name = '圆月弯剑' where book_id = 6; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from tb_book; +---------+-----------------------+--------+ | book_id | book_name | author | +---------+-----------------------+--------+ | 1 | 多情刀客无情刀 | 古龙 | | 2 | 笑傲江湖 | 金庸 | | 3 | 倚天屠龙记 | 金庸 | | 4 | 射雕英雄传 | 金庸 | | 5 | 绝代双骄 | 古龙 | | 6 | 圆月弯剑 | 古龙 | +---------+-----------------------+--------+ 6 rows in set (0.00 sec) mysql> rollback; Query OK, 0 rows affected (0.00 sec)