目录

  • 1. MVCC
  • 1.1. 概述
  • 1.2. 优缺点
  • 2. 乐观锁 & 悲观锁
  • 2.1. 乐观锁
  • 2.2. 悲观锁

1. MVCC


1.1. 概述

  1. MVCC使得大部分支持行锁的事务引擎,不再单纯的使用行锁来进行数据库的并发控制,取而代之的是把数据库的行锁与行的多个版本结合起来,只需要很小的开销,就可以实现非锁定读,从而大大提高数据库系统的并发性能。


1.2. 优缺点

MVCC在大多数情况下代替了行锁,实现了对读的非阻塞,读不加锁,读写不冲突。缺点是每行记录都需要额外的存储空间,需要做更多的行维护和检查工作。

  1. MVCC手段只适用于Msyql隔离级别中的读已提交(Read committed)和可重复读(Repeatable Read)
  2. Read uncimmitted由于存在脏读,即能读到未提交事务的数据行,所以不适用MVCC.
  1. 原因是MVCC的创建版本和删除版本只要在事务提交后才会产生。
  1. 串行化由于是会对所涉及到的表加锁,并非行锁,自然也就不存在行的版本控制问题。
  2. 通过以上总结,MVCC主要作用于事务性的,有行锁控制的数据库模型。

2. 乐观锁 & 悲观锁

2.1. 乐观锁

  1. 概述
  1. 在关系数据库管理系统里,乐观并发控制(又名“乐观锁”,Optimistic Concurrency Control,缩写“OCC”)是一种并发控制的方法。
  2. 它假设多用户并发的事务在处理时不会彼此互相影响,各事务能够在不产生锁的情况下处理各自影响的那部分数据。
  3. 在提交数据更新之前,每个事务会先检查在该事务读取数据后,有没有其他事务又修改了该数据。如果其他事务有更新的话,正在提交的事务会进行回滚。乐观事务控制最早是由孔祥重(H.T.Kung)教授提出。
  1. 本质
  1. 乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。
  2. 相对于悲观锁,在对数据库进行处理的时候,乐观锁并不会使用数据库提供的锁机制。一般的实现乐观锁的方式就是记录数据版本。
  3. 实现数据版本的方式: 使用版本号或使用时间戳
  1. 优点与不足
    乐观并发控制相信事务之间的数据竞争(data race)的概率是比较小的,因此尽可能直接做下去,直到提交的时候才去锁定,所以不会产生任何锁和死锁。

2.2. 悲观锁

  1. 概述
  1. 在关系数据库管理系统里,悲观并发控制(又名“悲观锁”,Pessimistic Concurrency Control,缩写“PCC”)是一种并发控制的方法。
  2. 它可以阻止一个事务以影响其他用户的方式来修改数据。如果一个事务执行的操作都某行数据应用了锁,那只有当这个事务把锁释放,其他事务才能够执行与该锁冲突的操作。
  3. 在MySQL中需要 关闭自动提交;
  1. 悲观锁 流程
  1. 在对任意记录进行修改前,先尝试为该记录加上排他锁(exclusive locking)。
  2. 如果加锁失败,说明该记录正在被修改,那么当前查询可能要等待或者抛出异常。 具体响应方式由开发者根据实际需要决定。
  3. 如果成功加锁,那么就可以对记录做修改,事务完成后就会解锁了。其间如果有其他对该记录做修改或加排他锁的操作,都会等待我们解锁或直接抛出异常。
  1. 优点与不足
  1. 悲观并发控制实际上是“先取锁再访问”的保守策略,为数据处理的安全提供了保证。
  2. 但是在效率方面,处理加锁的机制会让数据库产生额外的开销,还有增加产生死锁的机会;
  3. 另外,在只读型事务处理中由于不会产生冲突,也没必要使用锁,这样做只能增加系统负载;
  4. 还有会降低了并行性,一个事务如果锁定了某行数据,其他事务就必须等待该事务处理完才可以处理那行数

选择

  1. 乐观锁并未真正加锁,效率高。一旦锁的粒度掌握不好,更新失败的概率就会比较高,容易发生业务失败。
  2. 悲观锁依赖数据库锁,效率低。更新失败的概率比较低。

随着互联网三高架构(高并发、高性能、高可用)的提出,悲观锁已经越来越少的被使用到生产环境中了,尤其是并发量比较大的业务场景。