ACID(数据库事务要满足的要求)
Atomic(原子性) 事务必须是原子的工作单元(保证操作要么成功要么失败)
Consistent(一致性) 事务完成时,必须使所有数据都保持一致状态
Isolation(隔离性) 并发事务所做的修改必须和其他事务所做的修改是隔离的(通过锁来实现)
Duration(持久性) 事务完成之后,对系统的影响是永久性的
原子性与隔离性的要求导致事务操作比起非事务操作更加消耗系统性能
MySQL里的事务处理过程
1.记录redo(记录事务修改以后的数据)和undo(记录事务修改之前的数据)的log文件,确保日志在磁盘上的持久化
2.更新数据记录(更改数据库中的值)
3.提交事务,使用redo中的日志写入commit记录(事务处理完,清理undo文件,释放锁(确保隔离性),刷新redo日志)
分布式事务
分布式事务产生的原因:
1.数据库分表分库
2.服务SOA化
3.在分布式系统中,每一个机器节点虽然都能够明确知道自己执行的事务是成功还是失败,但是却没法知道其它分布式节点的事务执行情况。
因此,当一个事务要跨越多个分布式节点的时候(比如:下单流程,下单系统和库存系统可能就是分别部署在不同的分布式节点中),为了保证事务可以满足ACID,就要引用一个协调者(Cooradinator)。
其它的节点被称为参与者(Participant)。协调者负责调度参与者的行为,并最终决定这些参与者是否要把事务进行提交。
X/OpenDTP事务模型(分布式事务解决方案)
X/Open Distributed Transaction Processing Reference Model(全称:分布式事务处理模型)
X/Open是一个组织机构,定义出的一套分布式事务标准(具体的实现是由各个厂商来实现的), 定义了规范的API接口
2PC(two -phase-commit), 用来保证分布式事务的完整性(一个协议)
J2EE 遵循了X/open DTP规范,设计并实现了java里面的分布式事务编程接口规范-JTA
XA是X/Open DTP定义的中间件与数据库之间的接口规范。 XA接口函数由数据库厂商提供
(数据库层面用的都是XA规范)
X/OpenDTP角色
AP :application (应用节点)
RM :resouces manager 资源管理器。 (数据库)
TM :transaction manager 事务管理器,事务协调者
AP触发指令,TM协调调度RM,RM具体执行指令
2PC(two -phase-commit)(2阶段提交)
阶段一:
提交事务请求(投票)
1.TM向所有的AP发送事务内容,询问是否可以执行事务的提交操作,并等待各个AP的响应
2.执行事务
各个AP节点执行事务操作,将undo和redo信息记录到事务日志中,尽量把提交过程中所消耗时间的操作和准备都提前完成后确保后续事务提交的成功率
3.各个AP向TM反馈事务询问的响应
各个AP成功执行了事务操作,那么反馈给TM yes的response;如果AP没有成功执行事务,就反馈TM no的response
(只要任何AP返回no,就回滚(中断事务提交)保证原子性)
阶段二:
执行事务提交
假设一个事务的提交过程总共需要30s, 其中prepare(提交之前的准备)操作需要28(事务日志落地磁盘及各种io操作),而真正commit只需要2s那么,
commit阶段发生错误的概率和prepare相比,2/28 (<10%),只要第一个阶段成功,那么commit阶段出现失败的概率就非常小,
大大增加了分布式事务的成功概率。
中断事务提交
2PC存在的问题
1.数据一致性问题
2.同步阻塞
3PC(three phase commit)(2pc上的升级改造)
阶段一:canCommit
TM向AP发送can(是否可以执行,可以返回yes,不可以返回no)(只要有一个no,就中断事务)
阶段二:preCommit
TM根据阶段一的结果,判断是否可以执行commit操作(向AP发送可以操作请求),预执行
阶段三:doCommit
最后执行,所有参与者AP都确定可以commit
分布式事务的实现
1.JOTM(java open transaction manager)
2.Atomikos(开源项目集成了spring)