MySQL-数据库事务详解

目录

一、事务的ACID特性

二、事务的状态

三、使用事务

3.1、事务完成的过程

3.2、显示事务

3.3、隐式事务

3.4、事务隔离级别

3.4.1、事务问题

3.4.2 SQL的隔离级别

四、事务日志

4.1、redo 日志

4.2、undo日志


一、事务的ACID特性

  • 原子性:事务是一个不可分割的工作单位,要么全部提交,要么全部失败回滚;基础。
  • 一致性:数据从一个合法性变化成另一个合法性,这种状态是指语义上的,跟业务要求有关,需要满足约束,例如转账时超出总额;手段。
  • 隔离性:一个事务执行时不能被其他事务干扰,使用的数据对于其他并发的事务是隔离的,并发执行的各个事务之间不能互相干扰;约束条件。
  • 持久性:一个事务一旦提交,它对数据库中数据的改变是永久的,接下来的数据操作和故障不应该对其有任何影响。目的。

二、事务的状态

  • 活动的:事务对应的数据库操作正在执行过程中时;
  • 部分提交的:事务中的最后一个操作执行完成,但由于操作是在内存中执行的,所造成的影响并没有刷新到磁盘时,此时的状态为部分提交状态;
  • 失败的:事务处于活动的或者部分提交的状态时,可能遇到某些错误无法继续执行,此时为失败的状态;
  • 中止的:事务执行了一部分而变为失败的状态,那么就需要把已经修改的事务中的操作还原到事务执行前的状态。回滚完成时的状态;
  • 提交的:部分提交的数据修改持久化到磁盘上。

三、使用事务

3.1、事务完成的过程

步骤一:开启事务

步骤二:一系列的DML操作

步骤三:事务结束的状态:提交的状态(COMMIT)、中止的状态(ROLLBACK)

3.2、显示事务

步骤一:开启 使用关键字:start transaction 或 begin

start transation 后面可以跟:read only / read write (默认) / with consistent snapshot(启动一致性读)

步骤二:保存点

3.3、隐式事务

autocommit:是否自动提交

3.4、事务隔离级别

多个请求分布在不同事务中,可能同时请求更改一条数据,这时需要一种机制权衡并发性和隔离性。

3.4.1、事务问题

  • 脏写:一个事务A修改B未提交事务,此时B回滚,A修改的数据是无效的;

MySQL-数据库事务详解_第1张图片

  • 脏读:事务A读到了B未提交的事务,之后B回滚,A读取的内容是临时且无效的;

MySQL-数据库事务详解_第2张图片

  • 不可重复读:事务A读取一个字段,事务B更新一个字段,之后A再读同一个字段,值不同;

MySQL-数据库事务详解_第3张图片

  • 幻读:事务A从表中读取一个字段,事务B插入一些行,A再读同一个表就会多出几行;

MySQL-数据库事务详解_第4张图片

3.4.2 SQL的隔离级别

MySQL-数据库事务详解_第5张图片

mysql默认是可重复度隔离级别。

# 查看隔离级别
show variables like 'tx_isolation';
show variables like 'transaction_isolation';

# 设置隔离级别
set [global|session] transaction isolation level 隔离级别; 
set [global|session] transaction_isolation ='隔离级别' # 中划线链接

四、事务日志

实现事务特性的机制。

  • 事务的隔离都是由锁机制实现的;
  • 事务的原子性、一致性、持久性是由事务的redo日志和undo日志来保证;
  • redo log:重做日志,提供再写入操作,恢复提交事务修改的页操作,用来保证事务的持久性;物理级别上的修改。
  • undo log: 回滚日志,回滚行记录到某个特定版本,用来保证事务的原子性、一致性。逻辑上的修改。

4.1、redo 日志

好处:

  • redo日志降低了刷盘频率;
  • redo日志占用的空间非常小;

存储表空间id、页面、偏移量以及需要更新的值,所需的存储空间是很小的,刷盘快。

特点:

  • redo 日志是顺序写入磁盘的;
  • 事务执行过程中,redo log 不断记录;

redo 的组成:

  • 重做日志的缓冲,保存在内存中,是易失的;

MySQL-数据库事务详解_第6张图片

刷盘并不是真正刷入到磁盘,而是到文件系统缓冲中,再到磁盘中

MySQL-数据库事务详解_第7张图片

MySQL-数据库事务详解_第8张图片

4.2、undo日志

redo log是事务持久性的保证,undo log是日志原子性的保证,事务更新数据的前置操作其实是要先写入一个undo log。

  • 插入数据需要记录主键,回滚的时候根据主键对应的值进行删除;
  • 删除记录需要记录内容,回滚时再把由这些内容组成的记录插入到表中;
  • 修改记录需要把这条记录的旧值记录下来,回滚时再把这条记录更新为旧值就好了,对于每个update操作,Innodb存储引擎会执行一个相反的update,将修改前的行放回去;
  • undo日志的操作也会记录到redo 日志中,需要持久性的保护。
  • 作用:回滚数据;多版本并发控制

MySQL-数据库事务详解_第9张图片

你可能感兴趣的:(MySQL,数据库,mysql,java)