MySQL事务

事务特性

  • 原子性(atomicity)
  • 一致性(consistency)
  • 隔离性(isolation)
  • 持久性(durability)

事务隔离级别

READE UNCOMMITTED(未提交度)

允许脏读,也就是可能读取到其他会话中未提交事务修改的数据

READ COMMITTED(提交读)

只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)

REPEATABLE READE(可重复读)

可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读

SERIALIZABLE(可串行化)

完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

隔离级别 脏读 不可重复读 幻读
未提交读 可能 可能 可能
已提交读 不可能 可能 可能
可重复读 不可能 不可能 可能
可串行化 不可能 不可能 不可能

事务隔离级别名词解释

什么是脏读

脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。

什么是不可重复读

指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。

什么是幻读

指的是当某个事务在读取某个范围内的记录时, 另外一个事务又在该范围内插入了新的记录,当之前的事务再次 读取该范围的记录时,会产生幻行(Phantom Row)。

MySQL利用间隙锁解决了幻读

更改Mysql事务隔离级别

临时生效

SET @@session.transaction_isolation = 'READ-UNCOMMITTED';
SET session transaction isolation level read uncommitted;

永久性生效

打开Mysql配置文件增加如下:

transaction-isolation = READ-COMMITTED

查看Mysql事务隔离级别

# 全局配置
SELECT @@global.tx_isolation;

# 当前会话配置
select @@session.tx_isolation;

redo log 和 undo log

提到MySQL事务不得不说下,重做日志和回滚日志。

重做日志

基本概念

重做日志用来实现事务的持久性,即事务 ACID 中的 D。其由两部分组成:

  • 内存中的重做日志缓冲(redo log buffer)
  • 磁盘重做日志文件(redo log file)

核心原理:当提交一个事物,InnoDB存储引擎,必须完成 redo log 数据持久化,待事务 COMMIT 操作完成才算完成。另外重做日志还是满足幂等性。

重做日志块

重做日志是以512字节进行存储的。这意味着重做日志缓存、重做日志文件都是以块(block)的方式进行保存的,称之为重做日志块(redo log block),每块的大小为512字节。

若一个页中产生的重做日志数量大于512字节,那么需要分割为多个重做日志块进行存储。

重做日志块组成结构

重做日志相关参数

参数名 备注 默认值
innodb_log_file_size 重做日志文件大小 48M
innodb_log_files_in_group 指定重做日志文件组中文件的数量 2
innodb_log_group_home_dir 指定日志文件组所在的路径 ./
innodb_flush_log_at_trx_commit 控制ACID日志刷新到磁盘策略 1

回滚日志

基本概念

当提交一个事务时,Innodb自动把修改前的数据备份到 redo log 中,当提交失败或者系统异常奔溃可通过 redo log 实现回滚。

注意:redo log 是逻辑回滚。

快照读

MySQL利用 redo log 实现了非锁定读

事务A 修改 ID = 1 数据,此时MySQL会对该资源进行锁定(独占锁)

事务B 查询 ID = 1 数据,此时就属于快照度。因为事务A 原始数据已经被备份到 redo log 中。

undo log 格式类别

insert undo log

insert undo log是在insert操作中产生的undo log。因为insert操作的记录,只对事务本身可见,对其他事务不可见(这是事务隔离性要求),故该undo log可以在事务提交后直接删除。不需要进行purge操作。

update undo log

update undo log记录的是对 deleteupdate 操作产生的undo log。因MVCC机制存在,所有不能在事务提交时就进行删除。提交时放入 undo log 链表,等待purge线程进行最后的删除。

为什么不能在事务提交后立马删除?

ID 事务A 事务B
1 begin begin
2 - 删除ID=1数据
3 - commit
4 查询ID=1数据
5 commit

结论:如果事务B立马执行删除,这将导致事务A查不到任何数据,破坏了ACID特性。

原文地址:https://www.cnblogs.com/zhanghuizong/p/12674960.html