分布式事务
事务
严格意义上的事务实现应该是具备原子性、一致性、隔离性和持久性,简称ACID。
1、原子性:可以理解为一个事务内的所有操作要么都执行,要么都不执行。
2、一致性:可以理解为数据是满足完整性约束的,也就是不会存在中间状态的数据,比如你账上有400,我账上有100,你给我打200块,此时你的账上应该是200,我的账上的钱应该是300,不会存在我账上钱加了,你账上钱没扣的中间状态。
3、隔离性:指的是多个事务并发执行的时候不会互相干扰,即一个事务内的数据对于其他事务来说是隔离的。
4、持久性:指的是一个事务完成了之后数据就被永远保存下来,之后的其他操作或故障都不会对事务的结果产生影响。
而通俗意义上事务就是为了使得一些更新操作要么都成功,要么都失败。
分布式事务
分布式事务顾名思义就是要在分布式系统中实现事务,它其实是由多个本地事务组合而成。
对于分布式事务而言几乎满足不了ACID,其实对于单机事务而言大部分情况下也满足不了ACID,不然怎么会有四种隔离级别呢?所以更别说分布在不同数据库或者不同应用上的分布式事务了。
2PC(Two-phase commit protocol)
中文叫二阶段提交。二阶段提交是一种强一致性设计,2PC引入一个事务协调者的角色来协调管理各参与者(也可以称之为各本地资源)的提交和回滚,二阶段分别指的是准备(投票)和提交两个阶段。
准备阶段协调者会给各参与者发送准备命令,你可以把命令理解成除了提交事务之外啥事都做完了。同步等待所有资源的响应之后就进入第二阶段即提交阶段(注意提交阶段不一定是提交事务,也可能是回滚事务)。
假如在第一阶段所有参与者都返回准备成功,那么协调者则向所有参与者发送提交事务的命令,然后等待所有事务都提交成功之后,返回事务执行成功。
假如在第一阶段有一个参与者返回失败,那么协调者就会向所有参与者发送回滚事务的命令,即分布式事务执行失败。
第二阶段提交失败的话有两种情况:
1、第二阶段执行回滚事务操作:不断重试,直到所有参与者都会滚了,不然那些在第一阶段准备成功的参与者一直阻塞着。
2、第二阶段执行提交事务操作:不断重试,因为有可能一些参与者的事务已经提交成功了,这个时候只有一条路,就是不断重试,直到提交成功,到最后真的不行只能人工介入处理。
2PC是一个同步阻塞协议,像第一阶段协调者会等待所有参与者响应才会进行下一步操作,当然第一阶段的协调者有超时机制,假设因为网络原因没有收到某个参与者的响应或者某个参与者挂了,那么超时后就会判断事务失败,向所有参与者发送会滚命令。
在第二阶段协调者没法超时,因为按照我们上面分析只能不断重试!
协调者故障分析
协调者是一个单点,存在单点故障问题
1、协调者在发送准备命令之前挂了,还行等于事务还没开始。
2、协调者发送准备命令之后挂了,这就不太行了,有些参与着等于都执行了处于事务资源锁定状态。不仅事务执行不下去,还会因为锁定了一些公共资源而阻塞系统其他操作。
3、协调者发送回滚事务命令之前挂了,那么事务也是执行不下去,且在第一阶段那些准备成功参与者都阻塞着。
4、协调者发送回滚事务命令之后挂了,这个还行,至少命令发送出去了,很大的概率都会回滚成功,资源都会释放。但是如果出现网络分区问题,某些参与则会将因为收不到命令而阻塞着。
5、协调者发送提交事务之前挂了,这个不行,所有资源都阻塞着。
6、协调者发送提交事务之后挂了,这个还行,至少命令发送出去了,很大概率会提交成功,然后释放资源,但是如果出现网络分区问题某些参与者因为收不到命令而阻塞着。