01、事务的特性
原子性、一致性、隔离性和持久性
02、事务的隔离级别
脏读、不可重复读、幻读
03、CAP理论
是指能满足一致性、可用性和分区容错性的这三项其中的两项。
【1】、一致性
1、客户端:
得到的数据是最新数据
2、服务端:
分布式节点的数据保持一致性
3、对于一致性,一致的程度不同大体可以分为强、弱、最终一致性三类。
强一致性:要求更新的数据能马上访问到
弱一致性:能允许部分数据或者全部数据访问不到
最终一致性:经过一段时间后能访问到更新的数据
【2】、可用性
服务一直可用,并能正常的响应
【3】分区容错
当遇到某个节点或者网络故障的时候,依然能提供对外的一致性和可用性的服务。
【4】、总结
CAP理论只能满足其中的两种,绝大多数都满足牺牲一致性。但是这个也不一定主要还是根据实际的业务场景。
04、BASE理论
理论基础:既是无法做到强一致性,但每个应用都可以做到自身业务的特点,采用适当的方式达到最终一致性。
BASE的全称:Basically Available(基本可用),Soft state(软状态)和Eventually consistent(最终一致性)三个短语的缩写
1、Basically Available(基本可用)
响应时间上的损失和功能上的损失,保证系统可用
2、Soft state(软状态)
硬状态:相对于原子性而言,要求多个节点的数据副本都是一致的
软状态:允许系统中的数据存在中间状态,并认为该状态不影响系统的整体可用性,即允许系统在多个不同节点的数据副本存在数据延时。
3、Eventually consistent(最终一致性)
在一定的期限内,保证所有副本保持数据一致性。从而达到数据的最终一致性。
05、分布式系统的解决方案
【1】、XA接口
XA就是X/Open DTP定义的中间件与数据库之间的接口规范(即接口函数),中间件用它来通知数据库事务的开始、结束以及提交、回滚等
- 其中应用程序(Application Program ,简称AP):AP定义事务边界(定义事务开始和结束)并访问事务边界内的资源。
- 资源管理器(Resource Manager,简称RM):Rm管理计算机共享的资源,许多软件都可以去访问这些资源,资源包含比如数据库、文件系统、打印机服务器等。
- 事务管理器(Transaction Manager ,简称TM):负责管理全局事务,分配事务唯一标识,监控事务的执行进度,并负责事务的提交、回滚、失败恢复等。
采用两阶段的提交
【2】、JTA
Java Transaction API(Java事务API),JTA是基于XA架构上建模的,在JTA 中,事务管理器抽象为javax.transaction.TransactionManager接口,并通过底层事务服务(即JTS)实现。像很多其他的java规范一样,JTA仅仅定义了接口,具体的实现则是由供应商(如J2EE厂商)负责提供。
接口如下:
begin() 开始事务
commit() 提交事务
rollback() 回滚事务
getStatus() 返回当前事务状态
setRollbackOnly()
getTransaction() 返回关联到当前线程的事务
setTransactionTimeout(int seconds) 设置事务超时时间
resume(Transaction tobj) 继续当前线程关联的事务
suspend() 挂起当前线程关联的事务
【3】、2PC两节点提交
成功情况
失败情况
缺点:
2PC效率很低,分布式事务很难做。
1、某一个参与者发出通知之前,所有参与者以及协调者都处于阻塞状态;
2、在协调者发出通知之前,所有参与者都处于阻塞状态;
【4】、3PC三段提交
1、阶段一:CanCommit
事务询问
各个参与者节点向协调者反馈事务询问的响应
2、阶段二:PreCommit
根据阶段一的反馈结果分为两种情况
1、执行事务预提交
- 1)发送预提交请求
- 协调者向所有参与者节点发送preCommit请求,进入preparred阶段
- 2)事务预提交
- 各参与者节点向协调者反馈事务执行
2、中断事务
任意一个参与者节点反馈给协调者响应No时,或者在等待超时后,协调者还未收到参与者的反馈,就中断事务,中断事务分为两步:
- 1)协调者向各个参与者节点发送abort请求
- 2)参与者收到abort请求,或者等待超时时间后,中断事务
3、阶段三:doCommit
1、执行提交
- 1)发送提交请求
- 协调者向所有参与者节点发送doCommit请求
- 2)事务提交
- 各参与者节点收到doCommit请求后,执行事务提交操作
- 3)反馈事务提交结果
- 参与者节点完成事务提交以后,向协调者发送ack
- 4)事务完成
- 协调者接收各个参与者反馈的ack后,完成事务
2、中断事务
- 1)参与者接收到abort请求后,执行事务回滚
- 2)参与者完成事务回滚以后,向协调者发送ack
- 3)协调者接受回滚ack后,回滚事务
3PC相较于2PC而言,解决了协调者挂点后参与者无限阻塞和单点问题,但是仍然无法解决网络分区问题
2PC与3PC的区别?
相对于2PC,3PC主要解决的单点故障问题,并减少阻塞,因为一旦参与者无法及时收到来自协调者的信息之后,他会默认执行commit。而不会一直持有事务资源并处于阻塞状态。但是这种机制也会导致数据一致性问题,因为,由于网络原因,协调者发送的abort响应没有及时被参与者接收到,那么参与者在等待超时之后执行了commit操作。这样就和其他接到abort命令并执行回滚的参与者之间存在数据不一致的情况。
【5】、TCC事务
Try-Confirm-Cancel
- 先是服务调用链路依次执行 Try 逻辑。
- 如果都正常的话,TCC 分布式事务框架推进执行 Confirm 逻辑,完成整个事务。
- 如果某个服务的 Try 逻辑有问题,TCC 分布式事务框架感知到之后就会推进执行各个服务的 Cancel 逻辑,撤销之前执行的各种操作。
【6】、MQ分布式事物
采用时效性高的 MQ,由对方订阅消息并监听,有消息时自动触发事件
采用定时轮询扫描的方式,去检查消息表的数据
请参考 【 https://my.oschina.net/floor/blog/1587537 】
【7】、其他补偿
支付宝的回调页面和接口里,解密参数,然后调用系统中更新交易状态相关的服务,将订单更新为付款成功。同时,只有当我们回调页面中输出了 success 字样或者标识业务处理成功相应状态码时,支付宝才会停止回调请求。否则,支付宝会每间隔一段时间后,再向客户方发起回调请求,直到输出成功标识为止。
其实这就是一个很典型的补偿例子,跟一些 MQ 重试补偿机制很类似。
一般成熟的系统中,对于级别较高的服务和接口,整体的可用性通常都会很高。如果有些业务由于瞬时的网络故障或调用超时等问题,那么这种重试机制其实是非常有效的。
当然,考虑个比较极端的场景,假如系统自身有 bug 或者程序逻辑有问题,那么重试 1W 次那也是无济于事的。那岂不是就发生了“明明已经付款,却显示未付款不发货”类似的悲剧?
其实为了交易系统更可靠,我们一般会在类似交易这种高级别的服务代码中,加入详细日志记录的,一旦系统内部引发类似致命异常,会有邮件通知。同时,后台会有定时任务扫描和分析此类日志,检查出这种特殊的情况,会尝试通过程序来补偿并邮件通知相关人员。
在某些特殊的情况下,还会有“人工补偿”的,这也是最后一道屏障。
06、LCN框架
LCN并不生产事务,LCN只是本地事务的搬运工