1、先创建 1 张表
DROP TABLE IF EXISTS `avengers`;
CREATE TABLE `avengers` (
`id` int(11) NOT NULL,
`name` varchar(30) NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB;
INSERT INTO `avengers` VALUES (1, 'CaptainBritain');
INSERT INTO `avengers` VALUES (2, 'Hulk');
INSERT INTO `avengers` VALUES (3, 'Thor');
(1)模拟 脏读
客户端 1 设置最低隔离级别的 "读未提交",设置不自动提交事务:
mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
mysql> SET autocommit = 0;
在客户端 2 开启一个事务,在表中加入一条新的记录,先不提交。
mysql> BEGIN;
mysql> INSERT INTO `avengers` VALUES (4, 'SpiderMan');
在客户端 1 中,查看当前的表,看到了未提交的一条记录
mysql> select * from avengers;
+----+----------------+
| id | name |
+----+----------------+
| 1 | CaptainBritain |
| 2 | Hulk |
| 3 | Thor |
| 4 | SpiderMan |
+----+----------------+
此时客户端 2 可以回滚,造成脏读。
ROLLBACK;
(2)模拟 不可重复读
客户端 1 设置最低隔离级别的 "读已提交",
查看 id=1 的数据 :
mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
mysql> SET autocommit = 0;
mysql> BEGIN;
mysql> select * from avengers WHERE id=1;
+----+----------------+
| id | name |
+----+----------------+
| 1 | CaptainBritain |
+----+----------------+
客户端 2 对 id=1 的记录修改 name 为 IronMan 并自动提交 :
mysql> UPDATE `avengers` SET name = 'IronMan' WHERE id=1;
客户端 1 再次进行查询 id=1 的数据与之前不同了,对于客户端 1 来说,同一条查询语句出现了“不可重复读”。
mysql> select * from avengers where id=1;
+----+---------+
| id | name |
+----+---------+
| 1 | IronMan |
+----+---------+
(3)模拟 幻读
客户端 1 设置 "可重复读",查询数据表中的所有数据
mysql> SET autocommit = 0;
mysql> SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
mysql> BEGIN;
mysql> select * from avengers;
+----+---------+
| id | name |
+----+---------+
| 1 | IronMan |
| 2 | Hulk |
| 3 | Thor |
+----+---------+
客户端 2,插入新的数据并自动提交
mysql> INSERT INTO `avengers` VALUES (4, 'AntMan');
再用客户端 1 重新select,多出一条数据,出现幻读。
mysql> select * from avengers;
+----+----------------+
| id | name |
+----+----------------+
| 1 | CaptainBritain |
| 2 | Hulk |
| 3 | Thor |
| 4 | AntMan |
+----+----------------+
(4)可串行化
客户端 1 设置 "可串行化",再做上述实验,三种异常都不会出现了。
mysql> SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
网友评论