-
什么是事务?
对数据库的一系列操作,要么全执行,要么不执行.
事务时逻辑上的一组操作,要么全部执行,要么都不执行。 -
事务的三大特征
- 原子性 A 事务是最小执行单位,要么全部执行,要么都不执行
- 一致性 C 事务执行前后,事务保持一致。例如转账,二者总金额不变。
- 隔离性 I 各并发事务之间操作数据库是独立的
- 持久性 D 愿意各吃 事务提交,即使断电,也应保证状态被写入数据库
-
事务的四大特征如何保证
原子性 undo日志 (回滚)
持久性性 redo日志
隔离性 MVCC
一致性通过原子性 持久性 隔离性保证,我的理解是上面三个没有问题,持久性自然能够保证
-
事务并发带来的问题
- 脏读 一个事务读取了另一个未提交事务修改过的数据
W1(x) R2(x) T2提交 - 不可重复读
一个事务修改了另一个未提交数据读取的数据 强调内容修改或记录数减少
R1(x) W2(x) 再次读取,数据不一样了 - 幻读
一个事务根据某些查询条件查询出一些记录,事务未提交时,另一个事务写入一些符合条件的数据----->再次查询,两次结果不一致----》幻读==强调后来读取到了之前不存在的数据,可以是insert,也可以是update(符合标准)
==
- 脏读 一个事务读取了另一个未提交事务修改过的数据
-
脏写
一个事务修改了另一个未提交事务修改的数据
W1【X】 W2【2】 -
Mysql的四种隔离级别
- 读未提交
- 读已提交 --脏读
- 可重复性读 --不可重复性读
- 串行 – 脏读 ,不可重复读,幻读
-
什么是MVCC
多版本并发控制的缩写(Multi-Version-Concurency Control) -
mysql中是如何解决幻读的?或者说为什么解决不可重复度可以最大程度的避免脏读?
-
使用数据快照解决幻读 不可重复读问题 (多版本并发控制原理)
隐藏列中有 事务id 回滚指针
所有的事务分为三类 -
tx_id<m_ids 说明该事务已经提交,可见.
-
tx_id>=max_trx_id,说明这个事务在creator_trx_id创建后才创建,所以是不可见的
-
当 min_tx_id<=cur<max_tx_id时,事务可能已经提交,也可能为提交
如果已经提交,该版本是可见的,如果未提交,该版本不可见
10. 可重复性读是如何工作的
在select之前,创建一个readview(快照),当执行过程中,查到一条数据,查看该数据的版本,如果是可见,直接读出,如果是不可见的,通过回滚指针查找版本链,直到找到 trx_id 「小于」 Read View 中的 min_trx_id 值的第一条记录
11. 读已提交是如何工作的
每次执行语句前会创建一个快照,当B事务读取一条数据后,A对该数据进行了修改,B再次读取数据,会创建一个新的快照,由于B未提交,所以仍然会在当前活跃事务列表中,B再次读取会查找版本链.当A提交数据,B再次执行查询创建快照的时候会被归入 (-inf,max_tr_id)的已提交,会被判为可见.
12. MVCC是如何(部分的)解决幻读的
(1)如果是快照读,MVCC的可重复读可以(极大部分的)解决幻读
(2)如果是当前读,
MVCC通过建立快照,当隔离级别是可重复读时,第一次查询创建的快照在之后会一直使用,即使后续插入了新的数据,但是版本过高,会沿着版本链向前找,最后找到空.
- 什么情况下MVCC不能解决幻读
A 查询 id=5 (为空)
B 插入id=5
B T提交
A 更新id等于5的值 (更新是当前读操作)
A查询id=5 (由于更新,该记录事务id为自己,所以可以读到)
情况2: