事务中的脏写、脏读、不可重复读、幻读
首先来说一下事务中会发生的问题:脏写、脏读、不可重复读、幻读
假设id=5的记录最原始的username=“小王”
1.脏写
sessionA | sessionB |
---|---|
begin //开启事务 | |
begin//开启事务 | |
update user set username=“张三” where id=5; | |
commit//提交事务 | |
update user set username=“李四” where id=5; | |
ROllBACK; | |
1.sessionA开启了事务之后,紧接着sessionB也开启了事务,那么sessionB如果事务回滚就会回滚到最原始的记录,也就是sessionB开启事务之前的记录,也就是username为"小王"。
2.sessionA明明对id为5的记录进行了修改,而且sessionB也没有进行事务提交,只是进行了事务的回滚,这种情况就称为脏写。更改了别人修改的记录。
2.脏读
sessionA | sessionB |
---|---|
begin //开启事务 | |
begin//开启事务 | |
update user set username=“张三” where id=5; | |
select * from user where id =5; | |
COMMIT;//提交事务 | |
COMMIT;//提交事务 | |
sessionB会读取到username为张三的记录,这种情况就是脏读。
3.不可重复读
sessionA | sessionB |
---|---|
begin //开启事务 | |
select * from user where id =5; //读取到的是小王 | |
update user set username=“张三” where id=5;//这里有个隐式事务。自动提交 | |
select * from user where id =5; //读取到的是张三 | |
commit; | |
上面这种情况就是不可重复情况,在一个开启的事务中,同一个select语句能读取到的其他事务修改的值。
4.幻读
sessionA | sessionB |
---|---|
begin //开启事务 | |
select * from user where id >=5; | |
insert into user(id,username) values(6,‘老李’);//隐式事务,自动提交 | |
select * from user where id >=5; 此时读取到的就是除了之前有的 还多了一条老李的记录 | |
commit; | |
幻读就是相比第一条查询,第二条查询多了其他数据