**
悲观锁与乐观锁
**
一、定义:
悲观锁:在修改数据的时候,为了防止其他人同时修改该数据,导致出现数据的脏读、不可重复读等问题,我们可以借助数据库锁机制,对数据进行上锁,这时的锁是悲观锁。
乐观锁:乐观锁假设数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则返回给用户错误的信息,让用户决定如何去做。
二、区别
1.乐观锁并未真正加锁,效率高。一旦锁的粒度掌握不好,更新失败的概率就会比较高,容易发生业务失败,不安全。
乐观并发控制相信事务之间的数据竞争的概率是比较小的,因此尽可能直接做下去,直到提交的时候才去锁定,所以不会产生任何锁和死锁。
2.悲观锁依赖数据库锁,效率低。更新失败的概率比较低,更安全。
处理加锁的机制会让数据库产生额外的开销,还有增加产生死锁的机会。另外还会降低并行性,一个事务如果锁定了某行数据,其他事务就必须等待该事务处理完才可以处理那行数据。
三、实现原理
1.乐观锁
每次在执行数据的修改操作时,都会带上一个版本号,一旦版本号和数据的版本号一致就可以执行修改操作并对版本号执行+1操作,否则就执行失败,除了version以外,还可以使用时间戳,因为时间戳天然具有顺序递增性。
2.悲观锁:
在对记录进行修改前,先尝试为该记录加上排他锁,如果加锁失败,说明该记录正在被修改,那么当前查询可能要等待或者抛出异常。具体响应方式由开发者根据实际需要决定。
如果成功加锁,那么就可以对记录做修改,事务完成后就会解锁了。期间如果有其他对该记录做修改或加排他锁的操作,都会等待解锁或直接抛出异常。
口头阐述乐观锁和悲观锁:
1.乐观锁就是比较乐观,觉得别人不会同时修改数据,没有真正上锁,利用判断版本号或时间戳是否一致来执行修改操作,只是在提交修改的时候检查数据是否发生冲突,如果出错,返回给用户错误信息,让用户处理;乐观锁效率高,安全性低
2.悲观锁就是比较悲观,觉得别人会同时修改数据,修改前先对要修改的数据加排他锁,加锁失败则表示该数据正在被修改,那么就必须等待;如果加锁成功,那么就可以修改,事务完成后就会解锁。悲观锁效率低,安全性高