分布式事务的现象及理解

分布式事务

背景

在微服务环境下,因为会根据不同的业务会拆分成不同的服务,比如会员服务、订单服务、商品服务等,让专业的人做专业的事情,每个服务都有自己独立的数据库,并且是独立运行,互不影响。但是每个服务中都有自己独立的数据源,即自己独立的本地事务。两个服务相互通讯的时候,两个本地事务互不影响,从而出现分布式事务产生的原因。

案例说明: 下单和扣库存如何保持一致问题
描述: 数据库都是独立的,每个独立的数据源中都有自己独立的事务,该事务成为本地事务。本地事务有效范围在同一个jdbc里面(同一个事务管理器 )

分布式事务的现象及理解

代码展示:
分布式事务的现象及理解

问题: 下单失败了,但是库存成功了,如何去回滚? 注意: 下单成功,库存失败,不属于分布式事务问题。

总结: 本地数据源有效范围是 同一个jdbc连接或者同一个事务管理器。

分布式事务解决方案

刚性事务 -- 关系型数据库的ACID

关系型数据库天生就是解决具有复杂事务场景的问题,关系型数据库完全满足ACID的特性。满足ACID特性

ACID对应的含义:事务管理(ACID)

    谈到事务一般都是以下四点:

         原子性(Atomicity):原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

        一致性(Consistency):事务前后数据的完整性必须保持一致。

        隔离性(Isolation):事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。

        持久性(Durability):持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响

柔性事务 -- 遵循Base和CPA理论

CPA理论

  1. C:Consistency, 一致性。在分布式系统中的所有数据 备份,在同一时刻具有同样的值,所有节点在同一时刻读取的数据都是最新的数据副本。双方进行通讯的时候,或者服务器集群的时候,一定要保证数据一致性问题,不能发生脏读等问题。其实一般情况下可以做个取舍,可以暂时不遵循一致性,但是达到最终一致性,只要核心遵循下面的可用性和分区容忍性就可以。

  2. A:Availability,可用性,好的响应性能。完全的可用性指的是在任何故障模型下,服务都会在有限的时间内处理完成并进行响应。比如服务器宕机情况下 还有备机

  3. P: Partition tolerance,分区容错性。尽管网络上有部分消息丢失,但系统仍然可继续工作。

总结:

  • CAP原理指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。
  • 对于分布式数据系统,分区容忍性是基本要求,容错是肯定的,否则就失去了价值,在一致性和可用性之间取一个平衡
  • 对于大多数web应用,其实并不需要强一致性,因此牺牲一致性而换取高可用性,是目前多数分布式数据库产品的方向。
  • 通过软状态,可以暂时不一致,但是最终实现一致。通过补偿、重试等。
  • 牺牲一致性,只是不再要求关系型数据库中的强一致性,而是只要系统能达到最终一致性即可
  • 由于关系型数据库是单节点无复制的,因此不具有分区容忍性,但是具有一致性和可用性,而分布式的服务化系统都需要满足分区容忍性,那么我们必须在一致性和可用性之间进行权衡
注意实际开发中只遵循了P和A

Base 理论

  1. BA:(Basically Available),基本可用。指分布式系统在出现故障的时候,保证核心可用。比如:网页访问过大时,部分用户提供降级服务。
  2. S:(Soft State),软状态,状态可以在一段时间内不同步。
  3. E:(Eventually Consistent),最终一致,在一定的时间内,最终数据达成一致即可。

总结: BASE 思想与 ACID 原理截然不同,它满足CAP原理,通过牺牲强一致性获得可用性, 一般应用于服务化系统的应用层或者大数据处理系统中,通过达到最终一致性来尽量满足业务的绝大多数需求。

支付案例

分布式事务的现象及理解

流程如下:

  • toov5 调用支付宝时候 会传递两个参数 同步回调地址 和 异步回调地址
  • 同步回调地址:支付完成后,支付宝采用浏览器方式重定向回调方
  • 异步回调地址:支付完成后,采用后台也就是HttpClient进行调用toov5接口通知支付接口
  • 当通知接口出现延迟或者异常情况下,支付宝会发生自动重试。短暂的不一致情况

柔性事务分为:

  • 两阶段型
  • 补偿型
  • 异步确保型
  • 最大努力通知型

关于两阶段、三阶段

1. 两阶段: 交易中间件与数据库通过 XA 接口规范,使用两阶段提交来完成一个全局事务, XA规范的基础是两阶段提交协议。
  1. 准备阶段:协调者向参与者发起指令,参与者评估自己的状态,如果参与者评估指令可以完成,则会写redo或者undo日志(提交日志和回滚日志),然后锁定资源,执行操作,但并不提交。
  2. 提交阶段:协调者会向参与者发送一个指令,如果参与者收到指令后,会把该业务逻辑是否执行成功结果返回给协调者。如果参与者都返回执行成功,协调者在第二阶段发送提交事务通知,如果有一方执行失败,就会终止提交。

缺点:

  1. 如果协调者发生宕机,整个就没法指挥协调了。库存服务和订单服务会一直等待。
  2. 两阶段提交方案锁定资源时间长,对性能影响很大,基本不适合解决微服务事务问题。

技术落地:

  • Jta+Atomikos 属于两阶段提交协议。底层是基于XA协议,主流数据库MySQL等都支持XA协议。这个协议规范就是协调者把指令发送给参与者的过程。MySQL是参与者,Atomikos:Atomikos TransactionsEssentials是一个为Java平台提供增值服务的并且开源类事务管理器,底层就是遵循了XA协议的规范。
    Jta+Atomikos 代码案例
1. 三阶段提交协议 --- 两阶段准备阶段再加了一个询问阶段
  1. 询问阶段: 协调者询问参与者是否可以完成指令,协调者只需要回答是还是不是,而不需要做真正的操作,这个阶段超时导致中止。协调者和参与者执行的任务中都增加了超时,一旦超时,协调者和参与者都继续提交事务,默认为成功,这也是根据概率统计上超时后默认成功的正确性最大。

优点: 至少不会阻塞和永远锁定资源。


结合非关系型数据库
      • 但当数据库要开始满足横向扩展、高可用、模式*等需求时,需要对ACID理论进行取舍,不能严格遵循ACID。以CAP理论和BASE理论为基础的NoSQL数据库开始出现。
      • 由于NoSQL的基本需求就是支持分布式存储,严格一致性与可用性需要互相取舍,由此延伸出了CAP理论来定义分布式存储遇到的问题。
上一篇:李洪强iOS经典面试题140-UI


下一篇:MySQL ACID和隔离级别