一:读——读 情况
即并发事务相继读取相同的记录 .读取操作本身不会对记录有任何影响,
所以允许该情况的发生。
二:写——写 操作
实现原理:锁机制
在多个未提交事务
相继对一条记录做改动时,通过锁机制让多个事务
排队执行
。
(1): 当事务T1想要对某条记录进行修改,
首先会看看内存中有没有与这条记录关联的
锁结构 。
当没有的时候,
就会在内存中生成一个
锁结构
与之关联。
(2):当事务T2也想要对该记录进行修改时,发现已经存在和这条记录想关联的锁结构,
也产生一个锁结构,同时让当前事务等待
(3):当事务T1执行完毕之后,事务T2就可以执行了
注:在MySQL中,任何一种隔离情况都不会允许该情况发生
三:读——写操作
方案一:
读操作利用多版本并发控制( MVCC ,下章讲解),写操作进行 加锁 。
注:普通的
SELECT
语句在
READ COMMITTED
和
REPEATABLE READ
隔离级别下会使用到
MVCC
读取记录。
(1):在
READ COMMITTED
隔离级别下,一个事务在执行过程中每次执行
SELECT
操作时都会生成一个ReadView
,
ReadView
的存在就保证了
当前事务只能读到ReadView建立之前已提交的修改
,也就是避免了脏读现象;
(2):在
REPEATABLE READ
隔离级别下,一个事务在执行过程中只有
第一次执行
SELECT
操作
才会生成一个ReadView
,之后的
SELECT
操作都
复用
这个
ReadView
,这样也就避免了不可重复读
的问题
方案二:读写操作都使用加锁方式,见上图
小结对比:
(1):采用
MVCC
方式的话,
读
-
写
操作彼此并不冲突,
性能更高
。
(2):采用
加锁
方式的话,
读
-
写
操作彼此需要
排队执行
,影响性能。
(3):一般情况下我们当然愿意采用
MVCC
来解决
读
-
写
操作并发执行的问题,但是业务在某些特殊情况下,要求必须采用
加锁
的方式执行。