Sql分表分库

数据库并发控制——悲观锁、乐观锁、MVCC

2019-05-08  本文已影响0人  黄宝玲_1003

三种并发控制:悲观并发控制乐观并发控制多版本并发控制

悲观并发控制(又名“悲观锁”,Pessimistic Concurrency Control,缩写“PCC”)

在数据库管理系统(DBMS)中,悲观锁正是利用数据库本身提供的锁机制(行锁、表锁、排他锁、共享锁)来实现的(只有数据库层提供的锁机制才能真正保证数据访问的排他性)。

控制流程

1、对某记录进行修改前,尝试加排他锁。
2、如果加锁失败,说明该记录正在被修改,那么当前查询可能要等待或者抛出异常。 具体响应方式由开发者根据实际需要决定。
3、如果成功加锁,那么就可以对记录做修改,事务完成后就会解锁了。
4、其间如果有其他对该记录做修改或加排他锁的操作,都会等待我们解锁或直接抛出异常。

优缺点

优点
1、先取锁再访问,保证数据安全。
2、适用于写比较多的情况。
缺点
1、处理加锁的机制会让数据库产生额外的开销,还有增加产生死锁的机会;
2、在只读型事务处理中由于不会产生冲突,也没必要使用锁,这样做只能增加系统负载;
3、会降低了并行性,一个事务如果锁定了某行数据,其他事务就必须等待该事务处理完才可以处理那行数据。

乐观并发控制(又名“乐观锁”,Optimistic Concurrency Control,缩写“OCC”)

假设多用户并发的事务在处理时不会彼此互相影响,各事务能够在不产生锁的情况下处理各自影响的那部分数据。在提交数据更新之前,每个事务会先检查在该事务读取数据后,有没有其他事务又修改了该数据。如果其他事务有更新的话,正在提交的事务会进行回滚。
一般的实现乐观锁的方式就是记录数据版本(版本号或时间戳)。

控制流程

有记录record1, version=1
1、A读取并修改record1A, versionA=1
2、B读物并修改record1B, versionB=1
3、A提交修改前检查 versionA=version=1, 提交后 record=record1A, version=versionA+1=2
4、B提交修改前检查 versionB != version,事务回滚。

优缺点

优点
1、适用于读比较多的情况。
缺点
1、当写操作较多时,冲突会很频繁。

多版本并发控制 (Multi-Version Concurrency Control,缩写“MVCC”)

每个连接到数据库的读者,在某个瞬间看到的是数据库的一个快照,写操作在完成之前对读操作是不可见的。
MVCC 并发控制下的读事务一般使用时间戳或者事务 ID去标记当前读的数据库的状态(版本),读取这个版本的数据。读、写事务相互隔离,不需要加锁。读写并存的时候,写操作会根据目前数据库的状态,创建一个新版本,并发的读则依旧访问旧版本的数据。
MVCC允许数据具有多个版本,这个版本可以是时间戳或者是全局递增的事务ID,在同一个时间点,不同的事务看到的数据是不同的。

控制流程

看一下mysql的innodb引擎是如何实现MVCC的。innodb会为每一行添加两个字段,分别表示该行创建的版本和删除的版本,填入的是事务的版本号,这个版本号随着事务的创建不断递增。在repeated read的隔离级别下,具体各种数据库操作的实现:
select:
满足以下两个条件innodb会返回该行数据:(1)该行的创建版本号小于等于当前版本号,用于保证在select操作之前所有的操作已经执行落地。(2)该行的删除版本号大于当前版本或者为空。删除版本号大于当前版本意味着有一个并发事务将该行删除了。
insert:
将新插入的行的创建版本号设置为当前系统的版本号。
delete:
将要删除的行的删除版本号设置为当前系统的版本号。
update:
不执行原地update,而是转换成insert + delete。将旧行的删除版本号设置为当前版本号,并将新行insert同时设置创建版本号为当前版本号。

其中,写操作(insert、delete和update)执行时,需要将系统版本号递增。

由于旧数据并不真正的删除,所以必须对这些数据进行清理,innodb会开启一个后台线程执行清理工作,具体的规则是将删除版本号小于当前系统版本的行删除,这个过程叫做purge。

举例(TS 时间戳)
record1, createTime=1, deleteTime=9
record2, createTime=2
1、A读取record1,TS=2,读取成功。
2、A读取record1,TS=10,读取失败。此时该记录已被删除。
3、A读取record1,TS=0,读取失败。此时该记录还未被创建。
4、B要更新record2,TS=3,先读取,读取成功,创建新行record2,createTime=3,删除旧行record2, createTime=2, deleteTime=3

优缺点

优点
1、读操作永远不会被阻塞
2、实现了完整的快照隔离(乐观锁是不完整的快照隔离)
缺点
1、会存储多个版本数据的冗余开销。

总结:

三种并发控制对比:
PCC:性能损耗较高
OCC:不完整的快照隔离
MVCC:完整的快照隔离

上一篇下一篇

猜你喜欢

热点阅读