mysql脏写、脏读、幻读、不可重复读问题验证
0 相关数据 || 知识
1. mysql版本
2. 表格及数据
/*Table structure for table `user` */ DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` INT(11) NOT NULL, `name` VARCHAR(32) DEFAULT NULL, `desc` VARCHAR(20) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8; /*Data for the table `user` */ INSERT INTO `user`(`id`,`name`,`desc`) VALUES (1,'路人甲',NULL), (2,'路人乙',NULL);
3. 数据库隔离级别
Read Uncommitted(读取未提交内容): 存在脏读
Read Committed(读取提交内容):存在不可重复读
Repeatable Read(可重读):存在幻读
Serializable(可串行化):隔离级别最高,不存在前面的所有情况,因为串行执行,效率最低
4. 隔离级别查看和设置
//查看当前事物级别: SELECT @@tx_isolation; //设置mysql的隔离级别: set session transaction isolation level 设置事务隔离级别 //设置read uncommitted级别: set session transaction isolation level read uncommitted; //设置read committed级别: set session transaction isolation level read committed; //设置repeatable read级别: set session transaction isolation level repeatable read; //设置serializable级别: set session transaction isolation level serializable;
1 脏写
1. 定义:事务A和事务B同时更新一条记录,一个事务回滚导致另一个事务的改动丢失
2. 隔离级别设置:set session transaction isolation level read uncommitted;
由于innodb在update时,会加行锁, 事务1没结束,事务2的update会阻塞,天然避免了脏写
2 脏读
1. 定义:读取到了事务未提交改动
2. 设隔离级别设置:set session transaction isolation level read uncommitted;
3. 窗口1为事务执行窗口,窗口2为观察窗口
4. 怎么避免:将mysql隔离级别设置成read committed及以上,或者加行锁
3.不可重复读
1. 定义:在事务中多次查询同一条数据,得到结果不一样
2. 设隔离级别设置:set session transaction isolation level read committed;
3. 窗口1为执行窗口,窗口2为观察窗口
4. 怎么避免:将mysql隔离级别设置成repeatable read及以上
4.幻读
1. 定义:在事务中多次查询同一张表数据,得到结果不一样
2. 设隔离级别设置:set session transaction isolation level read committed;
3. 窗口1为事务执行窗口,窗口2为观察窗口
4. 怎么避免:将mysql隔离级别设置成repeatable read及以上,或加表锁
5.事务开启时,未执行select时,表数据改动生效,一旦执行select,会生成表格快照,查询不到改动
Become a Linux Programmer