一、死锁
1.死锁是什么?
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去,进入无限等待的状态。
2.示例
死锁示例事务2等待事务1释放 字段0 = 1 的行锁,事务1等待事务2 字段0=2 的行锁,进入死锁状态。
3.解决策略
A.等待直到超时;可通过innodb_lock_wait_timeout参数来设置等待时间,默认值为 50s。
B.回滚其中一个事务,让其他事务继续进行;此设置需通过下面这个参数开启,“ON”即开启。
C.预防策略:控制并发度
二、悲观锁和乐观锁
1.含义
乐观锁和悲观锁都是并发场景下控制数据处理过程的主要方法。
悲观锁(Pessimistic Locking):每次去拿数据的时候都认为别人会修改数据,所以每次拿数据的时候,都会使数据处于锁定状态。
乐观锁(Optimistic Lock):每次去拿数据的时候都认为别人不会修改数据,所以不会上锁,仅会在数据进行提交更新的时候,才会去检查别人有没有对数据进行修改(检查是否冲突)。
2.实现思路简述
以一个比较经典的实现场景为例,“购买物品,生成订单并修改库存数量”,大致会进行以下三个步骤的操作:
A.查询物品信息;
B.根据物品信息生成订单数据;
C.更新库存数量。
悲观锁:
悲观锁在进行A操作“查询物品信息”时,就会给对应的数据上锁;
例如:
select * from goods where id = 1 for update;
直接以排他锁的形式锁定了对应的数据。
(这里有一个注意点:"select ... for update" 会锁住sql语句执行过程中所有扫描过的数据行,所以,你应该确保这条sql语句使用了索引)
乐观锁:
使用“数据版本”的机制,为数据库增加一个“数据版本”的字段(每次有更新操作时,都会 版本号+1);
当我们读取数据时,同时读取版本号;如果要更新数据,则需要同时更新版本号(version+1);当我们更新数据的时候,要将读取数据时的版本号和现在数据库中的版本号进行对比,如果相同,则更新,反正,则更新失败,由用户自行决定后面的逻辑处理。
萌新初入江湖,有理解不足之处,望指正!
参考资料:
网友评论