Mysql丢失修改问题解决
1.首先理解mysql的读锁和写锁和mvcc
select * from … for update
update …
insert …
delete …
均为写锁
select * from … for share mode
为读锁
select * from … 根据事务隔离区别确定,此时不加锁,根据mvcc
模式,控制读取版本
- 丢失修改问题
业务中通常理解丢失修改问题,通常为在一个事务中先读后写。 两个事务并发执行。 - 事务1 查询一行数据放在本地缓存,并且显示给用户user1 -->select balance from account where user= ‘a’ ;
2. 事务2 查询同样的一行数据放在本地缓存,并且显示给用户user2 -->select balance from account where user= ‘a’ ;
3. 用户user1修改这条数据,并且更新提交数据库 --> update account set balance = 上一次读出来的值 -100 where user= ‘a’ ;
4. 用户user2修改显示的数据,并且更新提交数据库 --> update account set balance = 上一次读出来的值 -800 where user= ‘a’ ;
此时,在一个事务中出现读写,就会发生这种情况, 所以为了解决这种情况,通常可使用悲观锁和乐观锁的方式来处理。
悲观锁的方法也就是select * from … for update. 然后在执行update,
这种情况会对当前数据加锁。 并且只有在事务提交或回滚时,才释放锁。此时事务二没办法获取数据。 重点是,事务提交后才释放锁。
乐观锁的方法是通过查询出来的版本或者update_time的时间戳等,在修改时加入作为判断逻辑。
2. 注意
修改数据时注意:是否用到了上一次读出来的数据,如果在一个事务内,利用上一次读出来的数据修改,就会发生错误,(可在幻读的基础上理解),所以修改时要注意加判断逻辑(乐观锁)。