乐观锁:
- 假设认为数据一般情况下不会产生并发冲突,所以在数据进行提交更新的时候,才会对数据是否产生并发冲突进行检测,如果发现并发冲突了,则让返回用户错误的信息,让用户决定如何去做。
- 乐观锁大多是基于数据版本记录机制,即数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个 “version” 字段来实现。读取数据后获取数据的版本号,更新数据时将此版本号加一。当我们提交更新的时候,判断当前版本信息与第一次取出来的版本值大小,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数据,拒绝更新,让用户重新操作。(总需要竞争锁,发生线程切换,效率不高)
- ABA问题可以用乐观锁来避免
- 乐观锁适用于多读的应用类型,这样可以提高吞吐量
悲观锁:
- 总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以在每次拿数据的时候都会上锁,这样别人想拿到这个数据就会阻塞直到它拿到锁。
- 悲观锁大部分是依据数据库的锁机制来实现,以保证操作最大程度的独占性。但随之而来的是数据库性能的大量开销。
- 并不总是能处理所有问题,所以会引入一定的系统复杂度。
两种锁都有优缺点,我们并不能说一种好于另一种,而是在进行应用时根据不同场景进行选择。像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行retry,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。