事务特性
- Atomicity原子性:同一个事务中的操作,要么全做,要么全不做。
- Consistency一致性:事务的执行会使数据库从一个一致性状态到另一个一致性状态。
- Isolation隔离性:不同的事务之间的执行互不影响。
- Durability持久性:事务提交后对数据库的影响是永久性的。
分布式事务
- 单数据源的事务中,事务包含的操作都针对同一个数据库,因此可以利用数据库本身的提供的事务机制(例如mysql的innodb引擎就支持事务)实现。
- 对于分布式系统来说,同一个事务可能包含针对多个节点上的资源操作,这些操作要么全做要么全不做。由于分布式节点之间通过网络进行通信,因此分布式事务无法采取与单数据源事务相同的解决方案。
分布式事务实现方式
- 事务协调者:管理整个事务的组件
- 事务参与者:负责具体资源的操作以及管理,如数据库
两阶段提交
- 准备阶段:事务协调者询问事务参与者是否可以提交事务。
- 提交阶段:如果所有事务参与者都同意,则提交事务。
- 存在问题:如果协调者宕机,参与者将会阻塞等待。并且如果协调者提议后某个参与者跟着宕机,其它参与者会进入无法回滚无法提交的状态。
三阶段提交
- 准备阶段
- 预提交阶段
- 提交阶段
- 解决的问题:参与者宕机。阶段一:未收到宕机参与者的投票,协调者终止事务,参与者恢复后终止事务。阶段二:协调者未收到宕机参与者的ack,发出commit,参与者恢复后自动根据vote结果或者precommit指令进行提交。阶段三:协调者未收到宕机参与者的commit ack, 结束该事务,参与者恢复后自动提交。(可能造成数据不一致)。
- 存在问题:数据不一致。
TCC(Try,Confirm,Cancel)
类似于两阶段提交。
- 准备阶段:Try;资源准备阶段,锁住所需要的资源。
- 提交阶段:Confirm;Try阶段成功后则提交。
- 取消阶段:Cancel;如果Try或者Confirm阶段出现问题,则撤销资源锁定。
事务状态表
-
建立事务状态表,表项包含事务ID、各个操作的状态、事务内容等;
-
启动后台任务扫描这张表,如果存在某个操作未完成,则重新调用该操作。由于可能存在多次调用同一个操作,因此需要进行任务幂等性设计。
-
如果多次调用后未达到完成状态,则应该对该事务标记为失败,并进行特殊处理。
基于消息中间件
- 事务发起者进行事务操作,并将该操作记录到数据库。这两个操作应放到同一个本地事务中,从而保证数据一致性。
- 后台任务将数据库中的记录发送到消息队列,确认发送成功后则删除该条记录。
- 事务被动发起方接受到消息队列的消息,查询去重表中是否已存在该记录,执行消息对应的操作,将执行后的操作记录到去重表中,返回ACK给消息队列。