MySQL-悲观锁及乐观锁

悲观锁

悲观锁( Pessimistic Locking ) 是一种思想,对数据被其他事务的修改持保守态度,会通过数据库自身的锁机制来实现,从而保证数据操作的排它性

可以理解为独占锁。

悲观锁的调用一般是在所要查询的语句后面加上FOR UPDATE

当数据库执行… FOR UPDATE时会获取被操作的数据行的行锁,获取的行锁会在当前事务结束时自动释放,因此必须在事务中使用

如果其他事务只是简单的查询而没有用FOR UPDATE的话,那么查询还是不会受影响的。

乐观锁

乐观锁( Optimistic Locking ) 思想认为对同一数据的并发操作不会总发生,属于小概率事件,不用每次都对数据上锁,也就是不采用数据库自身的锁机制,而是通过程序来实现。

先进行业务操作,只在最后实际更新数据时进行检查数据是否被更新过。实际应用时使用版本号和CAS算法实现。

CAS

CAS( Compare-And-Swap ) 是一种无锁的思想,它假设线程对资源的访问是没有冲突的,同时所有的线程执行都不需要等待,可以持续执行。如果遇到冲突的话,就使用CAS来鉴别线程冲突,如果检测到冲突发生,就重试当前操作到没有冲突为止。

缺点

CAS算是比较高效的并发控制手段,不会阻塞其他线程。但是,这样的更新方式是存在问题的,但是如果结果一直跟预期的结果不一样的话,线程就会一直不断的循环重试,重试次数太多的话对CPU也是一笔不小的开销。

使用场景

  • 悲观锁适合写操作多的场景,因为写的操作具有排它性。采用悲观锁的方式,可以在数据库层面阻止其他事务对该数据的操作权限,防止读 - 写和写 - 写的冲突。
  • 乐观锁适合读操作多的场景,相对来说写的操作比较少。它的优点在于程序实现,不存在死锁问题,不过适用场景也会相对乐观,因为它阻止不了除了程序以外的数据库操作。