目录
一、事务的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修改的数据是无效的;
- 脏读:事务A读到了B未提交的事务,之后B回滚,A读取的内容是临时且无效的;
- 不可重复读:事务A读取一个字段,事务B更新一个字段,之后A再读同一个字段,值不同;
- 幻读:事务A从表中读取一个字段,事务B插入一些行,A再读同一个表就会多出几行;
3.4.2 SQL的隔离级别
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 的组成:
刷盘并不是真正刷入到磁盘,而是到文件系统缓冲中,再到磁盘中
4.2、undo日志
redo log是事务持久性的保证,undo log是日志原子性的保证,事务更新数据的前置操作其实是要先写入一个undo log。
- 插入数据需要记录主键,回滚的时候根据主键对应的值进行删除;
- 删除记录需要记录内容,回滚时再把由这些内容组成的记录插入到表中;
- 修改记录需要把这条记录的旧值记录下来,回滚时再把这条记录更新为旧值就好了,对于每个update操作,Innodb存储引擎会执行一个相反的update,将修改前的行放回去;
- undo日志的操作也会记录到redo 日志中,需要持久性的保护。
- 作用:回滚数据;多版本并发控制