[转]MySQL数据库事务隔离级别–实例讲解
事务隔离级别是指多个事务同时操作数据库时,事务之间相互隔离的程度,SQL 92规范有四种隔离级别,MySQL InnoDB存储引擎也支持这四种级别:
下面我们通过实例来讲解这四种隔离级别,首先创建一个表并插入一条记录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
CREATE TABLE `checking` ( `customer_id` int(11) NOT NULL, `customer_name` varchar(255) DEFAULT NULL, `balance` decimal(16,4) DEFAULT NULL, `create_date` datetime DEFAULT NULL, `update_date` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`customer_id`), KEY `idx_customer_id` (`customer_id`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
1 2 3 4 5 6 7 8 9 10 11 |
-- ---------------------------- -- Records of checking -- ---------------------------- INSERT INTO `checking` VALUES ('1002', 'Jane', '500.0000', '2018-11-01 09:57:08', '2018-11-08 16:34:09'); INSERT INTO `checking` VALUES ('1003', 'Tom', '300.0000', '2018-11-01 09:57:08', '2018-11-08 16:34:09'); INSERT INTO `checking` VALUES ('1004', 'John', '600.0000', '2018-11-01 09:57:08', '2018-11-08 16:34:09'); |
1. 一、事务的四种隔离级别–读未提交
Step1:事务A
1. 设置当前session的事务隔离级别为读未提交
2. 开始事务
3. 查询客户1002的余额为500
Step2:事务B
1. 设置当前session的事务隔离级别为读未提交
2. 开始事务
3. 更新客户1002的余额为800
4. 事务还没有提交
Step3:事务A
1. 再次查询客户1002的余额为,值800
2. 尽管事务B还没有提交
3. 如果事务B回滚了,那么事务A查询到的信息就脏数据
甲读,乙改,甲读,乙回滚,脏
2. 二、事务的四种隔离级别–读已提交
Step1:事务A
1. 设置当前session的事务隔离级别为读已提交
2. 开始事务
3. 查询客户1002的余额为500
Step2:事务B
1. 设置当前session的事务隔离级别为读已提交
2. 开始事务
3. 更新客户1002的余额为800
4. 事务还没有提交
Step3:事务A
1. 再次查询客户1002的余额,值仍然为500
2. 事务B还没有提交,所以解决了脏读的问题
Step4:事务B
1. 提交事务
2. 确认余额为800
Step5:事务A
1. 再次查询客户1002的余额,值变成了800
1. 事务A并还没有提交,但这次读到的数据不一样了,产生
不可重复读的问题
甲读,乙改,甲读,不脏;乙提交,甲读,不重
3. 三、事务的四种隔离级别–可重复读
Step1:事务A
1. 设置当前session的事务隔离级别为可重复读
2. 开始事务
3. 查询表中的所有记录,一共三条
Step2:事务B
1. 设置当前session的事务隔离级别为可重复读
2. 开始事务
3. 向表中插入一条记录,customer_id=1100
Step3:事务A
1. 不管事务B有没有提交,都查不到事务B插入的数据
2. 避免了不可重复读的问题,通过MVCC机制实现
Step4:事务A
1. 把customer_id为1100的余额更新为460
2. 再次查询,发现表中有了四条记录,产生了幻读
3. 可以通过加锁读取最新的数据
甲读,乙改,不重,甲改已所改,甲再查,幻
4. 四、事务的四种隔离级别–串行化
Step1:事务A
1. 设置当前session的事务隔离级别为串行化
2. 开始事务
3. 查询表中的所有记录,一共三条
Step2:事务B
1. 设置当前session的事务隔离级别为串行化
2. 开始事务
3. 向表中插入一条新的记录
4. 最后提示超时的错误
5. 串行化会强制把事务按照串行的方式执行,效率很低
总结:
[source]MySQL数据库事务隔离级别–实例讲解