分布式数据一致性(4)

分布式事务

1.1 两阶段提交(2PC)

    当应用逐渐扩展,出现一个应用使用多个数据源的情况,这个时候本地事务已经无法满足数据一致性的要求。由于多个数据源的同时访问,事务需要跨多个数据源管理,分布式事务应运而生。其中最流行的就是两阶段提交(2PC),分布式事务由事务管理器(TM)统一管理。

    两阶段提交分为准备阶段和提交阶段。

1fbf461bf497146064b6df6d96b025a95c8.jpg

    两阶段提交-commit

    3ddb475261c23b952e46c01a3683974673e.jpg

    两阶段提交-rollback

    在 JavaEE 平台下,WebLogic、Webshare 等主流商用的应用服务器提供了 JTA 的实现和支持。而在 Tomcat 下是没有实现的,这就需要借助第三方的框架 Jotm、Automikos 等来实现,两者均支持 Spring 事务整合。

 

    然而,两阶段提交也不能完全保证数据一致性问题,并且有同步阻塞的问题,所以其优化版本三阶段提交(3PC)被发明了出来。

1.2 三阶段提交(3PC)

96276fae018ae30ccb5a43038fac1472d65.jpg

    然而3PC也只能保证绝大多数情况下的数据一致性。

 

2.spring中的分布式事务处理

    spring中的分布式事务可以使用JTA来处理,多个数据源事务的同步。但是,JTA实现的分布式事务,有一定的性能问题。所以,很多时候都是不使用JTA来实现分布式事务的。

    因此,大多时候,用最终一致性代替强一致性。

  • 两阶段型  2PC

    就是分布式事务两阶段提交,对应技术上的XA、JTA/JTS。这是分布式环境下事务处理的典型模式。

 

  • 补偿型   TCC(Try Confirm Cancel)模式

    TCC型事务(Try/Confirm/Cancel)可以归为补偿型;TCC思路是:尽早释放锁;在Try成功的情况下,如果事务要回滚,Cancel将作为一个补偿机制,回滚Try操作; 
    TCC各操作事务本地化,且尽早提交 (放弃两阶段约束);当全局事务要求回滚时,通过另一个本地事务实现“补偿”行为; 
    TCC是将资源层的两阶段提交协议转换到业务层,成为业务模型中的一部分;

 

  • sagas模式  Axon 框架实现 

    将一个长事务,分解成一系列有序的本地事务。每个事务更新数据库或发送消息,来触发下一个本地事务;如果本地事务执行失败,soga会有序执行补偿事务,来回滚之前的操作。

 

  • 异步确保型   本地消息表/消息队列实现   

    将一些同步阻塞的事务操作变为异步的操作,避免对数据库事务的争用,典型例子是热点账户异步记账、批量记账的处理。

 

  • 可靠消息传递   消息队列实现   

     前一个事件发生,后一个事件一定发生。

 

  • 最大努力通知型   

    分布式事务中要求最低的一种, 也可以通过消息中间件实现, 与前面异步确保型操作不同的一点是, 在消息由MQ Server投递到消费者之后, 允许在达到最大重试次数之后正常结束事务.

 

3.微服务架构的分布式事务处理:

c3c647762b8ae691498380d4e1b39546919.jpg

下图中,若调用user微服务出错,则订单操作会被回滚。此时,数据保持一致。

27940ef1b2b32d3c0a14e15ff16b014b479.jpg

下图中,若调用票仓微服务出错,user微服务则无法进行回滚。

b1b169d681b60daf13846884cf3039464fc.jpg

解决方案1:尽可能减少服务间的调用

解决方案2:没有服务间的调用,通过消息驱动调用服务。

基于消息队列实现的微服务分布式事务:

e6196036e9c02b259eb953a1dd8a1c1fa7f.jpg

需要注意的问题:

    1.消息中间件需要支持事务;

    2.如何处理重试的消息:

        通过全局id,幂等性校验(确保无论重试几次,返回的结果都应当不会变化,保证多次重试不会对系统造成其他影响。)

    3.发生业务异常时的回滚操作

        解决1.把出错的失败消息写入一个队列中,进行相应的回滚操作

        解决2.通过定时任务检查超时订单,对未完成的订单做自动回滚

        解决3.保存出错信息,人工处理。

a024620ee38ea18b602f07c7d506d16b55f.jpg

 

 

总结:

3fb0166d8184904f49ecc44d231e432b622.jpg

    使用幂等性UUID,防止错误处理时重试对数据造成多次处理。

    分布式锁,防止多次相同请求,短时间内重复处理多次。

ae881f6f97f53fedafcf423d991147d3a6c.jpg

    1.一般情况下,使用最终一致性即可满足业务上的需求;

    2.合理地选择同步还是异步进行处理;

    3.合理地设计实现代码:设计的原则为 越容易出现错误的代码,越应当优先进行检查和处理;这样可以保证在对数据修改之前,对可能出现的错误情形都考虑到了,然后尽早地返回结果。

    从而尽可能地减小 分布式事务出现错误回滚的情况。

c2eb92d7557df7b8ab24e7d8e1bd6178d07.jpg

参考文章:

1.《微服务下的数据一致性的几种实现方式之概述》https://www.jianshu.com/p/b264a196b177

转载于:https://my.oschina.net/langwanghuangshifu/blog/3080116

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值