事务(Transaction)是数据库区别于文件系统的重要特性之一。
数据库引入事务的主要目的:事务会把数据库从一种抑制状态转换为另一种一致状态。在数据库提交工作时,要么所有修改都已经保存了,要么所有修改都不保存。
InnoDB中的事务完全符合ACID的特性
- 原子性(atomicity)
- 一致性(consistency)
- 隔离性(isolation)
- 持久性(durability)
7.1 事务概述
事务用来保证数据库的完整性
原子性:事务中所有操作要么全部成功,要么全部失败
一致性:从一种状态转变为下一种一致状态。事务开始前和结束后,数据库的完整性约束没有被破坏。
隔离性:一个事务的影响在提交前对其他事务都不可见
持久性:一旦提交,结果就是永久性的。
7.2 事物的实现
隔离性由锁实现
原子性,一致性,持久性通过数据库的Redo Undo实现
7.2.1 redo
- 事务日志由重做日志(redo)文件和InnoDB日志缓冲(InnoDB Log Buffer)实现。
- 当开始一个事务时,会记录该事务的
LSN,日志序列号。 - 事务执行时,会往InnoDB日志缓冲里插入事务日志。
- 事务提交时,必须将InnoDB日志缓冲写入磁盘,再写数据,即预写日志方式。从而保证数据完整性
7.2.2 undo
undo存放在数据库内部的一个特殊段中,成为undo段,undo段位于共享表空间内。
undo只能逻辑上还原,并不能物理上还原
7.3 事务控制语句
- START TRANSACTION | BEGIN : 显示的开启一个事务,存储过程中只能使用START TRANSACTION。
- COMMIT :提交事务,并使得一堆数据库做的所有修改成为永久性的。commit work在completion_type不同时会执行不同的操作。
- ROLLBACK :结束事务并撤销正在进行的所有未提交的修改。
- SAVEPOINT identifier:SAVEPOINT允许你在事务中创建一个保存点,一个事务中可以有多个SAVEPOINT。
- RELEASE SAVEPOINT identifier:删除一个保存点,当没有保存点时会报错,此条回滚并不会像ROLLBACK一样结束事务。
- ROLLBACK TO [SAVEPOINT] identifier:这个语句与SAVEPOINT命令一起使用。回滚到保存点位置
- SET TRANSACTION:这个语句用来设置事务的隔离级别。
7.4 隐式提交的SQL语句
以下语句会隐式提交事务
![](https://img.haomeiwen.com/i5350978/fa50263cf6557aff.png)
Microsoft SQL Server 中DDL不会隐式提交,这一点与InnoDB和Oracle不同
7.5 对于事务操作的统计
TPS计算:
(com_committed + com_rollback) / time
但是这种方法的前提是所有的事务都必须是显示提交的。如果存在饮食的提交和回滚(默认autocommit=1),不会计算到com_commit和com_rollback中
7.6 事务的隔离级别
隔离级别有四个
- READ UNCOMMITTED
- READ COMMITTED
- REPEATABLE READ
- SERIALIZABLE
InnoDB默认为REPEATABLE READ ,通过Next-Key Lock锁的算法,避免了幻读,已经能完全保证事务的隔离性要求。
7.7 分布式事务
- InnoDB支持XA事务,通过XA事务可以支持分布式事务的实现。
- 分布式事务指允许多个独立的事务资源参与一个全局的事务中。全局事务要求参与的事务要么都提交,要么都回滚,所以对于事务原有的ACID有了更高的要求。另外,使用分布式事务时,InnoDB事务隔离级别必须是SERIALIABLE。
-
XA事务允许不同数据库之间的分布式事务。
分布式事务模型
分布式事务使用两段式提交(two-phase commit)的方式。
- 在第一个阶段,所有参与的节点都开始准备(PREPARE),告诉事务管理器他们准备好提交了。
- 第二个阶段,事务管理器告诉资源管理器执行ROLLBACK还是COMMIT。如果任何一个节点显示不能提交,则所有节点都被告知需要回滚。
7.8 不好的事务习惯
7.8.1 在循环中提交
循环中重复提交,或者隐式提交,都会重复写入重做日志,造成资源浪费。
7.8.2 使用自动提交
7.8.3 使用自动回滚
无法获取返回值和报错信息,所以事务的控制应该交给程序端。
网友评论