认识事务
事务是数据库区别于文件系统的重要特性之一。事务可以吧数据库从一个一致性状态转换为另一个一致性状态。
innerdb引擎的事务保证了acid。
- 原子性
- 一致性
- 隔离性
- 持久性
事务的分类
- 扁平的事务
所有事务中最简单的,生产环境中使用最频繁的。在扁平事务中,所有操作处于同一层次,由begin work开始,到commit work或者rollback work结束,这期间的操作是原子的,要么全成功要么全失败
- 带有保存节点的扁平事务
一个事务执行失败,期间的操作全失败,这样代价太大,所以允许在事务期间的某个状态设置保存点,这样可以回滚的时候,这个回滚到这个状态点。对于扁平事务而言,有个隐藏的保存点,就是begin work的时候
- 链事务
保存点模式事务如果系统崩溃,那么就不会保存如何保存点。链事务就是来解决这个问题的,每个事务都会记录上个事务的执行结果,但是回滚也只能回滚到上个事务节点,下图解释了链事务的工作方式
- 分布式事务
是指允许多个独立的数据源参与到全局事务中。那么全局事务要求,参与其中的事务要么全部执行成功,要么全部失败。innerdb内部是用基于xa协议来实现的,由两阶段提交,和三阶段提交。内部由一下组件组成
- 资源管理器
- 事务管理器
- 应用程序
-
2阶段提交
1.请求阶段(commit-request phase,或称表决阶段,voting phase)
在请求阶段,协调者将通知事务参与者准备提交或取消事务,然后进入表决过程。
在表决过程中,参与者将告知协调者自己的决策:同意(事务参与者本地作业执行成功)或取消(本地作业执行故障)。2.提交阶段(commit phase)
在该阶段,协调者将基于第一个阶段的投票结果进行决策:提交或取消。
当且仅当所有的参与者同意提交事务协调者才通知所有的参与者提交事务,否则协调者将通知所有的参与者取消事务。
参与者在接收到协调者发来的消息后将执行响应的操作。 -
3阶段提交
1.CanCommit阶段
3PC的CanCommit阶段其实和2PC的准备阶段很像。
协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应。2.PreCommit阶段
Coordinator根据Cohort的反应情况来决定是否可以继续事务的PreCommit操作。
根据响应情况,有以下两种可能。
A.假如Coordinator从所有的Cohort获得的反馈都是Yes响应,那么就会进行事务的预执行:
发送预提交请求。Coordinator向Cohort发送PreCommit请求,并进入Prepared阶段。
事务预提交。Cohort接收到PreCommit请求后,会执行事务操作,并将undo和redo信息记录到事务日志中。
响应反馈。如果Cohort成功的执行了事务操作,则返回ACK响应,同时开始等待最终指令。
B.假如有任何一个Cohort向Coordinator发送了No响应,或者等待超时之后,Coordinator都没有接到Cohort的响应,那么就中断事务:
发送中断请求。Coordinator向所有Cohort发送abort请求。
中断事务。Cohort收到来自Coordinator的abort请求之后(或超时之后,仍未收到Cohort的请求),执行事务的中断。3.DoCommit阶段
该阶段进行真正的事务提交,也可以分为以下两种情况:
执行提交
A.发送提交请求。Coordinator接收到Cohort发送的ACK响应,那么他将从预提交状态进入到提交状态。并向所有Cohort发送doCommit请求。
B.事务提交。Cohort接收到doCommit请求之后,执行正式的事务提交。并在完成事务提交之后释放所有事务资源。
C.响应反馈。事务提交完之后,向Coordinator发送ACK响应。
D.完成事务。Coordinator接收到所有Cohort的ACK响应之后,完成事务。
中断事务
Coordinator没有接收到Cohort发送的ACK响应(可能是接受者发送的不是ACK响应,也可能响应超时),那么就会执行中断事务。
ps: 参考资料《MySQL技术内幕++InnoDB存储引擎》,https://www.cnblogs.com/AndyAo/p/8228099.html