什么是悲观锁和乐观锁
- 悲观锁: 悲观锁就是每次拿数据的时候就会以为别人在修改,持有一种悲观的态度,所以每次在拿数据的时候都会上锁,Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现,每次拿数据都是一个线程,完成后在进行其他进程。传统的数据库也用到了很多的锁机制,比如行锁、表锁、读锁、写锁等,他们在操作的时候总是先给上锁,对外界的访问持保守态度,保持自身的排他性。简而言之,悲观锁主要用于保护数据的完整性。当多个事务并发执行时,某个事务对数据应用了锁,则其他事务只能等该事务执行完了,才能进行对该数据进行修改操作。
悲观锁使用场景及性能:主要针对多次访问数据库进行修改多的时候,这样可以避免冲突,不然的话可能会产生幻读等异常现象。悲观锁依赖数据库锁,效率低。更新失败的概率比较低。 - 乐观锁:乐观锁就是相对于悲观锁而言的,主要有冲突检测和数据更新,主要的实现方式是乐观锁技术:CAS(Compare and Swap)。其每次拿数据的时候持开放态度,以为别人不会修改,所以不会一上来就给上锁,但是在更新的时候要首先去判断别人有没有即时更新这个数据,如果数据库表当前第一次取出来的数据相等,则予以更新,否则认为是过期数据。乐观锁每次在执行数据的修改操作时,都会带上一个版本号,一旦版本号和数据的版本号一致就可以执行修改操作并对版本号执行+1操作,否则就执行失败。每次操作的版本号都会随之增加,版本号只会增加不会减少。
乐观锁使用场景及性能:主要针对很少对数据库进行修改的时候,乐观锁并未真正加锁,效率高。一旦锁的粒度掌握不好,更新失败的概率就会比较高,容易发生业务失败。