Mysql事务
2020-12-11 本文已影响0人
macfee333
事务系列知识:
[图片上传失败...(image-8127f5-1607620428430)]
事务特性:
ACID:原子性(Atomicity)、一致性(Consistent)、隔离性(Isalotion)、持久性(Durable)
"原子性" 大致原理:
基于日志的Redo/Undo机制(将所有对数据的更新操作都写到日志中),Redo log用来记录某数据块被修改后的值,可以用来恢复未写入 data file 的已成功事务更新的数据;Undo log是用来记录数据更新前的值,保证数据更新失败能够回滚
redo log原理:
[图片上传失败...(image-676dde-1607620428430)]
- 执行update操作。
- 先将原始数据从磁盘读取到内存,修改内存中的数据。
- 生成一条重做日志写入redo log buffer,记录数据被修改后的值。
- 当事务提交时,需要将redo log buffer中的内容刷新到redo log file。
- 事务提交后,也会将内存中修改数据的值写入磁盘
- 原子性,是redo log记录了事务期间操作的物理日志,事务提交之前,并没有写入磁盘,保存在内存里,如果事务失败,数据库磁盘不会有影响,回滚掉事务内存部分即可。
- 持久性,redo log 会在事务提交时将日志存储到磁盘redo log file,保证日志的持久性
undo log原理:
undo log是逻辑日志,只是将数据库逻辑的恢复到原来的样子。并不能将数据库物理地恢复到执行语句或者事务之前的样子。虽然所有的逻辑修改均被取消了,但是数据结构和页本身在回滚前后可能不一样了
既然是逻辑日志,可以理解为它存储的是SQL, 在事务中使用的每一条 INSERT 都对应了一条 DELETE,每一条 UPDATE 也都对应一条相反的 UPDATE 语句。
[图片上传失败...(image-e198fc-1607620428430)]
Mysql事务隔离级别:
并发事务带来哪些问题?
- 脏读(Dirty read): 当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是“脏数据”,依据“脏数据”所做的操作可能是不正确的。
- 丢失修改(Lost to modify): 指在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务内的修改结果就被丢失,因此称为丢失修改。 例如:事务1读取某表中的数据A=20,事务2也读取A=20,事务1修改A=A-1,事务2也修改A=A-1,最终结果A=19,事务1的修改被丢失。
- 不可重复读(Unrepeatableread): 指在一个事务内多次读同一数据。在这个事务还没有结束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。
- 幻读(Phantom read): 幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。
[图片上传失败...(image-541975-1607620428430)]
查询、修改mysql事务隔离级别:
mysql8 查询:
select @@global.transaction_isolation,@@transaction_isolation;
mysql8修改:
set session transaction isolation level read committed;
-
READ-UNCOMMITTED:一个事务读到了另一个未提交事务修改过的数据,整个过程如下图
[图片上传失败...(image-bed452-1607620428430)] -
READ COMMITTED:一个事务能读到另一个已经提交事务修改后的数据
[图片上传失败...(image-6a6ff3-1607620428430)] -
REPEATABLE READ(InnoDB默认的隔离级别):事务能读到另一个已经提交的事务修改过的数据,但是第一次读过某条记录后,即使后面其他事务修改了该记录的值并且提交,该事务之后再读该条记录时,读到的仍是第一次读到的值,而不是每次都读到不同的数据
[图片上传失败...(image-17ecc1-1607620428430)] -
SERIALIZABLE:串行化
[图片上传失败...(image-a0602f-1607620428430)]
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
READ-UNCOMMITTED | √ | √ | √ |
READ-COMMITTED | × | √ | √ |
REPEATABLE-READ | × | x | √ |
SERIALIZABLE | × | × | × |
参考:
https://zhuanlan.zhihu.com/p/29166694
https://github.com/Snailclimb/JavaGuide/blob/master/docs/database/MySQL.md