精华内容
下载资源
问答
  • java分布式事务demo

    2020-04-06 22:40:06
    java分布式事务demo
  • Java分布式事务

    万次阅读 2020-07-16 17:00:36
    分布式事务介绍 事务拥有以下四个特性,习惯上被称为ACID特性:

    分布式事务介绍

    1.1 什么是事务

    数据库事务(简称:事务,Transaction)是指数据库执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成[由当前业务逻辑多个不同操作构成]。

    事务拥有以下四个特性,习惯上被称为ACID特性:

    原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。记录之前的版本,允许回滚。

    一致性(Consistency):一致性是指事务使得系统从一个一致的状态转到另一个一致状态。事务的一致性决定了一个系统设计和实现的复杂度,也导致了事务的不同隔离级别。事务开始和结束之间的中间状态不会被其他事务看到。

    隔离性(Isolation):多个事务并发执行时,并发事务之间互相影响的程度,比如一个事务会不会读取到另一个未提交的事务修改的数据。适当的破坏一致性来提升性能与并行度

    持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。每一次的事务提交后就会保证不会丢失。

    延申拓展:

    事务隔离性(面试):

    • 脏读:事务A修改了一个数据,但未提交,事务B读到了事务A未提交的更新结果,如果事务A提交失败,事务B读到的就是脏数据。
    • 幻读:在同一个事务中,同一个查询多次返回的结果不一致。事务A新增了一条记录,事务B在事务A新增提交前后各执行了一次查询操作,发现后一次比前一次多了一条记录。幻读是由于并发事务增加记录导致的,这个不能像不可重复读通过记录加锁解决,因为对于新增的记录根本无法加锁。
    • 不可重复读:在同一个事务中,对于同一份数据读取到的结果不一致。比如,事务B在事务A更新或删除提交前读到的结果,和提交后读到的结果可能不同。不可重复读出现的原因就是事务并发修改记录,要避免这种情况,最简单的方法就是对要修改的记录加锁,这会导致锁竞争加剧,影响性能。

    事务的隔离级别(面试):

    • Read Uncommitted(读未提交):最低的隔离级别,什么都不需要做,一个事务可以读到另一个事务未提交的结果。所有的并发事务问题都会发生。
    • Read Committed(读已提交):只有在事务提交后,其更新结果才会被其他事务看见。可以解决脏读问题。
    • Repeated Read(可重复读):在一个事务中,对于同一份数据的读取结果总是相同的,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。可以解决脏读、不可重复读。
    • Serialization:事务串行化执行,隔离级别最高,牺牲了系统的并发性。可以解决并发事务的所有问题。

    自行复习:spring事务的传播机制(spring事务面试必问)

     

    1.2 什么是分布式事务

    分布式事务指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上,且属于不同的应用,分布式事务需要保证这些操作要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同数据库的数据一致性。

    1.3 事务的演变

    1.3.1 单服务单数据库的本地事务

    事务仅限于对单一数据库资源的访问控制,架构服务化以后,事务的概念延伸到了服务中。倘若将一个单一的服务操作作为一个事务,那么整个服务操作只能涉及一个单一的数据库资源,这类基于单个服务单一数据库资源访问的事务,被称为本地事务(Local Transaction)。

     

    1.3.2 单一服务多数据库的分布式事务

    最早的分布式事务应用架构很简单,不涉及服务间的访问调用,仅仅是服务内操作涉及到对多个数据库资源的访问。

     

    1.3.3 多服务多数据库的分布式事务

    当一个服务操作访问不同的数据库资源,又希望对它们的访问具有事务特性时,就需要采用分布式事务来协调所有的事务参与者。在这种情况下,起始于某个服务的事务在调用另外一个服务的时候,需要以某种机制流转到另外一个服务,从而使被调用的服务访问的资源也自动加入到该事务当中来。下图反映了这样一个跨越多个服务的分布式事务:

     

    1.3.4 多服务多数据源的分布式事务

    如果将上面这两种场景(一个服务可以调用多个数据库资源,也可以调用其他服务)结合在一起,对此进行延伸,整个分布式事务的参与者将会组成如下图所示的树形拓扑结构。在一个跨服务的分布式事务中,事务的发起者和提交均系同一个,它可以是整个调用的客户端,也可以是客户端最先调用的那个服务。

     

    较之基于单一数据库资源访问的本地事务,分布式事务的应用架构更为复杂。在不同的分布式应用架构下,实现一个分布式事务要考虑的问题并不完全一样,比如对多资源的协调、事务的跨服务传播等,实现机制也是复杂多变。

    事务的作用:保证每个事务的数据一致性。

    1.4 CAP定理(面试)

    CAP 定理,又被叫作布鲁尔定理。对于设计分布式系统(不仅仅是分布式事务)的架构师来说,CAP 就是你的入门理论。

     

    C (一致性):对某个指定的客户端来说,读操作能返回最新的写操作。

    对于数据分布在不同节点上的数据来说,如果在某个节点更新了数据,那么在其他节点如果都能读取到这个最新的数据,那么就称为强一致,如果有某个节点没有读取到,那就是分布式不一致。

    A (可用性):非故障的节点在合理的时间内返回合理的响应(不是错误和超时的响应)。可用性的两个关键一个是合理的时间,一个是合理的响应。

    合理的时间指的是请求不能无限被阻塞,应该在合理的时间给出返回。合理的响应指的是系统应该明确返回结果并且结果是正确的,这里的正确指的是比如应该返回 50,而不是返回 40。

    P (网络分区容错性):当出现网络分区后,系统能够继续工作。打个比方,这里集群有多台机器,有台机器网络出现了问题,但是这个集群仍然可以正常工作。

     

    2 分布式事务解决方案(面试)

    1.XA两段提交(强一致)

    2.TCC三段提交(强一致)

    3.本地消息表(MQ+Table)(最终一致)

    4.事务消息(RocketMQ[alibaba])(最终一致)

    5.Seata(alibaba)

    6.RabbitMQ的ACK机制实现分布式事务(拓展)

     

    一致性拓展:

    • 强一致性:读操作可以立即读到提交的更新操作。
    • 弱一致性:提交的更新操作,不一定立即会被读操作读到,读操作读到最新值需要一段时间。
    • 最终一致性:是弱一致性的特例。事务A更新一份数据后,最终一致性保证在没有其他事务更新同样的值的话,最终所有的事务都会读到事务A更新的最新值。如果没有错误发生,不一致时间的长短依赖于:通信延迟,系统负载等。

     

    2.1 基于XA协议的两阶段提交(2PC)

    X/Open 组织(即现在的 Open Group )定义了分布式事务处理模型

    XA协议:XA 是 X/Open 定义的交易中间件与数据库之间的接口规范(即接口函数),交易中间件用它来通知数据库事务的开始、结束以及提交、回滚等, XA 接口函数由数据库厂商提供。

    两阶段提交协议(Two Phase Commitment Protocol)中,涉及到两种角色

    一个事务协调者(coordinator):负责协调多个参与者进行事务投票及提交(回滚) 多个事务参与者(participants):即本地事务执行者

    总共处理步骤有两个 (1)投票阶段(voting phase):协调者将通知事务参与者准备提交或取消事务,然后进入表决过程。参与者将告知协调者自己的决策:同意(事务参与者本地事务执行成功,但未提交)或取消(本地事务执行故障);

    (2)提交阶段(commit phase):收到参与者的通知后,协调者再向参与者发出通知,根据反馈情况决定各参与者是否要提交还是回滚;

     

     

    如果任一资源管理器在第一阶段返回准备失败,那么事务管理器会要求所有资源管理器在第二阶段执行回滚操作。通过事务管理器的两阶段协调,最终所有资源管理器要么全部提交,要么全部回滚,最终状态都是一致的

     

    优点: 尽量保证了数据的强一致(无法完全保证),适合对数据强一致要求很高的关键领域。

    缺点:

    • 同步阻塞问题:执行过程中,所有参与节点都是事务阻塞型的。当参与者占有公共资源时,其他第三方节点访问公共资源不得不处于阻塞状态。
    • 单点故障:由于协调者的重要性,一旦协调者发生故障。参与者会一直阻塞下去。尤其在第二阶段,协调者发生故障,那么所有的参与者还都处于锁定事务资源的状态中,而无法继续完成事务操作。(如果是协调者挂掉,可以重新选举一个协调者,但是无法解决因为协调者宕机导致的参与者处于阻塞状态的问题)
    • 数据不一致:在二阶段提交的阶段二中,当协调者向参与者发送commit请求之后,发生了局部网络异常或者在发送commit请求过程中协调者发生了故障,这回导致只有一部分参与者接受到了commit请求。而在这部分参与者接到commit请求之后就会执行commit操作。但是其他部分未接到commit请求的机器则无法执行事务提交。于是整个分布式系统便出现了数据部一致性的现象。
    • 二阶段无法解决的问题:协调者再发出commit消息之后宕机,而唯一接收到这条消息的参与者同时也宕机了。那么即使协调者通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没人知道事务是否被已经提交

     

    2.2 三段提交(3PC)

    三段提交是两段提交的升级版

    CanCommit阶段:询问阶段

     

     

    类似2PC的准备阶段,协调者向参与者发送CanCommit请求,询问是否可以执行事务提交操作,然后开始等待参与者的响应。

     

    PreCommit阶段:事务执行但不提交阶段

     

    协调者根据参与者的反应情况来决定是否可以进行事务的PreCommit操作:

    • 协调者从所有的参与者获得的反馈都是Yes响应

      1. 发送预提交请求协调者向参与者发送PreCommit请求;
      2. 参与者接收到PreCommit请求后,执行事务操作,并将undo(执行前数据)和redo(执行后数据)信息记录到事务日志中;
      3. 参与者成功的执行了事务操作,则返回ACK(确认机制:已确认执行)响应,同时开始等待最终指令。
    • 有任何一个参与者向协调者发送了No响应,或者等待超时

      1. 协调者向所有参与者发送中断请求请求。
    1. 参与者收到来自协调者的中断请求之后(或超时之后,仍未收到协调者的请求),执行事务的中断。

     

    doCommit阶段:事务提交阶段

     

    • 执行提交

      1. 协调接收到所有参与者返回的ACK响应后,协调者向所有参与者发送doCommit请求。
      2. 参与者接收到doCommit请求之后,执行最终事务提交,事务提交完之后,向协调者发送Ack响应并释放所有事务资源。
      3. 协调者接收到所有参与者的ACK响应之后,完成事务。
    • 中断事务

      1. 协调者没有接收到参与者发送的ACK响应(可能是接受者发送的不是ACK响应,也可能响应超时),协调者向所有参与者发送中断请求;
      2. 参与者接收到中断请求之后,利用其在阶段二记录的undo信息来执行事务的回滚操作,并在完成回滚之后,向协调者发送ACK消息,释放所有的事务资源。
      3. 协调者接收到参与者反馈的ACK消息之后,执行事务的中断。

       

    优点:相对于2PC,3PC主要解决的单点故障问题,并减少阻塞,因为一旦参与者无法及时收到来自协调者的信息之后,他会默认执行commit。而不会一直持有事务资源并处于阻塞状态。

    缺点:会导致数据一致性问题。由于网络原因,协调者发送的中断响应没有及时被参与者接收到,那么参与者在等待超时之后执行了commit操作。这样就和其他接到中断命令并执行回滚的参与者之间存在数据不一致的情况。

     

    2.3 TCC补偿机制

    TTCC 其实就是采用的补偿机制,其核心思想是:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。三个阶段如下:

    操作方法含义
    Try预留业务资源/数据效验-尝试检查当前操作是否可执行
    Confirm确认执行业务操作,实际提交数据,不做任何业务检查。try成功,confirm必定成功
    Cancel执行业务出错时,需要回滚数据的状态下执行的业务逻辑

    其核心在于将业务分为两个操作步骤完成。不依赖事务协调器对分布式事务的支持,而是通过对业务逻辑的分解来实现分布式事务。

     

    例如: 小红要向小白转账100元,执行流程:

    1. 首先在 Try 阶段,要先调用远程接口检查小红的账户余额是否大于等于100元,若足够则对余额进行冻结,检查小白的账户状态是否正常。
    2. 在 Confirm 阶段,执行远程调用的转账的操作,扣除小红账户100元,小白账户加100元。
    3. 如果第2步执行成功,那么转账成功,小红账户解冻,流程结束。
    4. 如果第二步执行失败,则调用服务A的Cancel方法,账户余额回滚100元及解冻小红账户,同时调用服务B的Cancel方法,账户扣除100元。

    优点: 跟2PC比起来,实现以及流程相对简单了一些。

    缺点:

    • 在2 3 4步中都有可能失败,从而导致数据不一致。
    • TCC属于应用层的一种补偿方式,需要程序员在实现的时候多写很多补偿的代码,复杂业务场景下代码逻辑非常复杂。
    • 幂等性无法确保。

     

    2.4 本地消息表(异步确保)

    本地消息表这种实现方式应该是业界使用最多的,其核心思想是将分布式事务拆分成本地事务进行处理,这种思路是来源于ebay。我们可以从下面的流程图中看出其中的一些细节:

     

    工作流程:

    1. 消息生产方,需要额外建一个消息表,并记录消息发送状态。消息表和业务数据要在一个事务里提交,也就是说他们要在一个数据库里面。然后消息会经过MQ发送到消息的消费方。如果消息发送失败,会进行重试发送。
    2. 消息消费方,需要处理这个消息,并完成自己的业务逻辑。此时如果本地事务处理成功,表明已经处理成功了,如果处理失败,那么就会重试执行。如果是业务上面的失败,可以给生产方发送一个业务补偿消息,通知生产方进行回滚等操作。
    3. 生产方和消费方定时扫描本地消息表,把还没处理完成的消息或者失败的消息再发送一遍。

     

    优点: 一种非常经典的实现,避免了分布式事务,实现了最终一致性。

    缺点: 消息表会耦合到业务系统中,如果没有封装好的解决方案,会有很多杂活需要处理。

     

    2.5 MQ 事务消息

    有一些第三方的MQ是支持事务消息的,比如RocketMQ,他们支持事务消息的方式也是类似于采用的二阶段提交,但是市面上一些主流的MQ都是不支持事务消息的,比如 RabbitMQ 和 Kafka 都不支持(RabbitMQ、Kafka基于ACK机制)。

    以阿里的 RocketMQ 中间件为例,流程为:

    1. 发送一个事务消息,这个时候,RocketMQ将消息状态标记为Prepared,注意此时这条消息消费者是无法消费到的。
    2. 执行业务代码逻辑。
    3. 确认发送消息,RocketMQ将消息状态标记为可消费,这个时候消费者才能真正消费到这条消息。
    4. 如果步骤3确认消息发送失败,RocketMQ会定期扫描消息集群中的事务消息,如果发现了Prepared消息,它会向消息发送端(生产者)确认。RocketMQ会根据发送端设置的策略来决定是回滚还是继续发送确认消息。这样就保证了消息发送与本地事务同时成功或同时失败。

    正常流程图:

     

    完整流程图:

     

    优点: 实现了最终一致性,不需要依赖本地数据库事务。

    缺点: 目前主流MQ中只有RocketMQ支持事务消息。

     

    延申拓展:

    MQ非事务消息实现:

    • 方案一:创建独立消息服务
    • 方案二:使用非事务MQ(RabbitMQ/Kafka)的ACK机制

     

    2.6 Seata

    2.6.1 Seata简介

    2019 年 1 月,阿里巴巴中间件团队发起了开源项目 Fescar(Fast & EaSy Commit And Rollback),和社区一起共建开源分布式事务解决方案。Fescar 的愿景是让分布式事务的使用像本地事务的使用一样,简单和高效,并逐步解决开发者们遇到的分布式事务方面的所有难题。

    Fescar 开源后,蚂蚁金服加入 Fescar 社区参与共建,并在 Fescar 0.4.0 版本中贡献了 TCC 模式。

    为了打造更中立、更开放、生态更加丰富的分布式事务开源社区,经过社区核心成员的投票,大家决定对 Fescar 进行品牌升级,并更名为 Seata,意为:Simple Extensible Autonomous Transaction Architecture,是一套一站式分布式事务解决方案。

    Seata 融合了阿里巴巴和蚂蚁金服在分布式事务技术上的积累,并沉淀了新零售、云计算和新金融等场景下丰富的实践经验。

     

    核心组件:

    • Transaction Coordinator (TC): 事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚。
    • Transaction Manager (TM): 控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议。
    • Resource Manager (RM): 控制分支事务,负责分支注册、状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚。

     

    工作流程:

    1. TM 向 TC 申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的事务ID(XID),XID 在微服务调用链路的上下文中传播。
    2. RM 向 TC 注册分支事务,接着执行这个分支事务并提交事务(重点:RM在此阶段就已经执行了本地事务的提交/回滚),最后将执行结果汇报给TC。
    3. TM 根据 TC 中所有的分支事务的执行情况,发起全局提交或回滚决议。
    4. TC 调度 XID 下管辖的全部分支事务完成提交或回滚请求。

     

    2.6.2 Seata支持的模式

    seata中有两种常见分布式事务实现方案,AT及TCC

    • AT模式:赖于RM拥有本地数据库事务的能力,对于客户业务无侵入性

    • TCC 模式

       

    2.6.3 Seata的优点

    对业务无侵入:即减少技术架构上的微服务化所带来的分布式事务问题对业务的侵入 高性能:减少分布式事务解决方案所带来的性能消耗(2PC)

     

    2.6.4 AT模式

    Seata AT模式是基于XA事务演进而来的一个分布式事务中间件,XA是一个基于数据库实现的分布式事务协议,本质上和两阶段提交一样,需要数据库支持,Mysql5.6以上版本支持XA协议,其他数据库如Oracle,DB2也实现了XA接口。

    AT模式分为两个阶段,如下:

    • 第一阶段:本地数据备份阶段
    1. Seata 的 JDBC 数据源代理通过对业务 SQL 的解析,把业务数据在变化前后的数据镜像组织成回滚日志(XID/分支事务ID(Branch ID/变化前的数据/变化后的数据)。将回滚日志存入一张日志表UNDO_LOG(需要手动创建),并对UNDO_LOG表中的这条数据形成行锁(for update)。若锁定失败,说明有其他事务在操作这条数据,它会在一段时间内重试,重试失败则回滚本地事务,并向TC汇报本地事务执行失败。
    2. 将回滚日志存入一张日志表UNDO_LOG(需要手动创建),并对UNDO_LOG表中的这条数据形成行锁(for update)。
    3. 若锁定失败,说明有其他事务在操作这条数据,它会在一段时间内重试,重试失败则回滚本地事务,并向TC汇报本地事务执行失败。

    这样,可以保证:任何提交的业务数据的更新一定有相应的回滚日志存在

     

    目的:

    1. 基于这样的机制,分支的本地事务便可以在全局事务的第一阶段提交,并马上释放本地事务锁定的资源。
    2. 有了回滚日志之后,可以在第一阶段释放对资源的锁定,降低了锁范围,提高效率,即使第二阶段发生异常需要回滚,只需找对undolog中对应数据并反解析成sql来达到回滚目的。
    3. Seata通过代理数据源(DataSource->DataSourceProxy)将业务sql的执行解析成undolog来与业务数据的更新同时入库,达到了对业务无侵入的效果

     

    第二阶段:全局事务提交/回滚

    • 全局提交

      1. 所有分支事务此时已经完成提交,所有分支事务提交都正常。
      2. TM从TC获知后会决议执行全局提交,TC异步通知所有的RM释放UNDO_LOG表中的行锁,同时清理掉UNDO_LOG表中刚才释放锁的那条数据。

     

    • 全局回滚

      1. 若任何一个RM一阶段事务提交失败,通知TC提交失败。
      2. TM从TC获知后会决议执行全局回滚,TC向所有的RM发送回滚请求。
      3. RM通过XID和Branch ID找到相应的回滚日志记录,通过回滚记录生成反向的更新 SQL 并执行,以完成分支的回滚,同时释放锁,清除UNDO_LOG表中释放锁的那条数据。

     

    2.6.5 TCC模式

    seata也针对TCC做了适配兼容,支持TCC事务方案,原理前面已经介绍过,基本思路就是使用侵入业务上的补偿及事务管理器的协调来达到全局事务的一起提交及回滚。

     

    展开全文
  • 简述分布式事务指事务的操作位于不同的节点上,需要保证事务的 AICD 特性。例如在下单场景下,库存和订单如果不在同一个节点上,就涉及分布式事务。解决方案在分布式系统中,要实现分布式事务,...

    简述

    分布式事务指事务的操作位于不同的节点上,需要保证事务的 AICD 特性。

    例如在下单场景下,库存和订单如果不在同一个节点上,就涉及分布式事务。

    解决方案

    在分布式系统中,要实现分布式事务,无外乎那几种解决方案。

    一、两阶段提交(2PC)

    两阶段提交(Two-phase Commit,2PC),通过引入协调者(Coordinator)来协调参与者的行为,并最终决定这些参与者是否要真正执行事务。

    1. 运行过程

    1.1 准备阶段

    协调者询问参与者事务是否执行成功,参与者发回事务执行结果。

    1.2 提交阶段

    如果事务在每个参与者上都执行成功,事务协调者发送通知让参与者提交事务;否则,协调者发送通知让参与者回滚事务。

    需要注意的是,在准备阶段,参与者执行了事务,但是还未提交。只有在提交阶段接收到协调者发来的通知后,才进行提交或者回滚。

    2. 存在的问题

    2.1 同步阻塞 所有事务参与者在等待其它参与者响应的时候都处于同步阻塞状态,无法进行其它操作。

    2.2 单点问题 协调者在 2PC 中起到非常大的作用,发生故障将会造成很大影响。特别是在阶段二发生故障,所有参与者会一直等待状态,无法完成其它操作。

    2.3 数据不一致 在阶段二,如果协调者只发送了部分 Commit 消息,此时网络发生异常,那么只有部分参与者接收到 Commit 消息,也就是说只有部分参与者提交了事务,使得系统数据不一致。

    2.4 太过保守 任意一个节点失败就会导致整个事务失败,没有完善的容错机制。

    二、补偿事务(TCC)

    TCC 其实就是采用的补偿机制,其核心思想是:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。它分为三个阶段:

    • Try 阶段主要是对业务系统做检测及资源预留

    • Confirm 阶段主要是对业务系统做确认提交,Try阶段执行成功并开始执行 Confirm阶段时,默认 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。

    • Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放。

    举个例子,假入 Bob 要向 Smith 转账,思路大概是:我们有一个本地方法,里面依次调用

    1. 首先在 Try 阶段,要先调用远程接口把 Smith 和 Bob 的钱给冻结起来。

    2. 在 Confirm 阶段,执行远程调用的转账的操作,转账成功进行解冻。

    3. 如果第2步执行成功,那么转账成功,如果第二步执行失败,则调用远程冻结接口对应的解冻方法 (Cancel)。

    优点: 跟2PC比起来,实现以及流程相对简单了一些,但数据的一致性比2PC也要差一些

    缺点: 缺点还是比较明显的,在2,3步中都有可能失败。TCC属于应用层的一种补偿方式,所以需要程序员在实现的时候多写很多补偿的代码,在一些场景中,一些业务流程可能用TCC不太好定义及处理。

    三、本地消息表(异步确保)

    本地消息表与业务数据表处于同一个数据库中,这样就能利用本地事务来保证在对这两个表的操作满足事务特性,并且使用了消息队列来保证最终一致性。

    1. 在分布式事务操作的一方完成写业务数据的操作之后向本地消息表发送一个消息,本地事务能保证这个消息一定会被写入本地消息表中。

    2. 之后将本地消息表中的消息转发到 Kafka 等消息队列中,如果转发成功则将消息从本地消息表中删除,否则继续重新转发。

    3. 在分布式事务操作的另一方从消息队列中读取一个消息,并执行消息中的操作。

    优点: 一种非常经典的实现,避免了分布式事务,实现了最终一致性。

    缺点: 消息表会耦合到业务系统中,如果没有封装好的解决方案,会有很多杂活需要处理。

    四、MQ 事务消息

    有一些第三方的MQ是支持事务消息的,比如RocketMQ,他们支持事务消息的方式也是类似于采用的二阶段提交,但是市面上一些主流的MQ都是不支持事务消息的,比如 RabbitMQ 和 Kafka 都不支持。

    以阿里的 RocketMQ 中间件为例,其思路大致为:

    第一阶段Prepared消息,会拿到消息的地址。第二阶段执行本地事务,第三阶段通过第一阶段拿到的地址去访问消息,并修改状态。

    也就是说在业务方法内要想消息队列提交两次请求,一次发送消息和一次确认消息。如果确认消息发送失败了RocketMQ会定期扫描消息集群中的事务消息,这时候发现了Prepared消息,它会向消息发送者确认,所以生产方需要实现一个check接口,RocketMQ会根据发送端设置的策略来决定是回滚还是继续发送确认消息。这样就保证了消息发送与本地事务同时成功或同时失败。

    优点: 实现了最终一致性,不需要依赖本地数据库事务。

    缺点: 实现难度大,主流MQ不支持,RocketMQ事务消息部分代码也未开源。

    总结

    通过本文我们总结并对比了几种分布式分解方案的优缺点,分布式事务本身是一个技术难题,是没有一种完美的方案应对所有场景的,具体还是要根据业务场景去抉择吧。阿里RocketMQ去实现的分布式事务,现在也有除了很多分布式事务的协调器,比如LCN等,大家可以多去尝试。

      作者 |  无敌是多么寂寞啊

    来源 |  urlify.cn/B7ru22

    
    有热门推荐????
    1.Java学习路线(基础,源码,项目,实战)
    2.2019年Java基础学习阶段最新学习视频(限时领取)
    3.2019年Java高级进阶学习视频(限时领取)
    4.最新学习资源,看者有份,快来领取吧!
    5.阿里资深技术专家教你如何快速成长为技术大牛!       
    关注Java编程指南公众号在后台回复:Java学习,我们为你整理了一份最新完整的学习线路,帮你快速成长。
    
    
    点赞是最大的支持 
    
    展开全文
  • 1.什么是分布式事务 在分布式系统中一次操作由多个系统协同完成,这种一次事务操作涉及多个系统通过网络协同完成的过程称为分布式事务,(强调的是多个系统通过网络协议同时完成一个事务过程) 2.分布式事务的产生的...

    1.什么是分布式事务

    在分布式系统中一次操作由多个系统协同完成,这种一次事务操作涉及多个系统通过网络协同完成的过程称为分布式事务,(强调的是多个系统通过网络协议同时完成一个事务过程)
    在这里插入图片描述

    2.分布式事务的产生的原因

    2.1 数据库分表分库

    当数据库的数据比较大的时候达到成千上万的数据的时候,我们就需要对数据库进行分表分库处理来实现对服务器的压力,这时候如何保证数据的一致性,就需要引入分布式事务;
    在这里插入图片描述
    2.2 应用SOA化
    所谓的SOA化就是把服务器进行拆分,单台服务器拆分为多台服务(根据业务型进行划分为多台服务),在我们只有一台服务的时候,为了保证数据一致性,我们都是使用的是数据的ACID来实现的,现在是多台服务器的时候,采用ACID已经无法满足我们的需求了;

    2.3 事务的ACID特性
    1、原子性
    在整个事务中操作,要不全部成功,要不全部失败,没有所谓的中间状态的出现,

    2、一致性
    事务的操作中,保证事务的一致性,

    3、隔离性
    事务与事务之间相互隔离互不影响,

    4、持久性
    事务结束以后所有的事务操作的结果都需要存入数据库中。

    3.分布式事务使用的场景

    3.1 支付

    最经典的场景就是支付了,一笔支付,是对买家账户进行扣款,同时对卖家账户进行加钱,这些操作必须在一个事务里执行,要么全部成功,要么全部失败。而对于买家账户属于买家中心,对应的是买家数据库,而卖家账户属于卖家中心,对应的是卖家数据库,对不同数据库的操作必然需要引入分布式事务。

    3.2 下单

    买家在电商平台下单,往往会涉及到两个动作,一个是扣库存,第二个是更新订单状态,库存和订单一般属于不同的数据库,需要使用分布式事务保证数据一致性。
    在这里插入图片描述

    CAP理论

    如何进行分布式事务控制?CAP理论是分布式事务处理的理论基础,CAP有助于我们了解分布式事务的处理方案。
    CAP理论是:分布式系统在设计时只能在一致性(Consistency),可靠性(Availability),分区容忍性(Partition Tolerance),满足两种,无法兼顾三种。
    在这里插入图片描述
    一致性(Consistency):服务A、B、C三个节点都存储了用户信息数据,三个节点的数据需要保持同一时刻数据的一致;
    可靠性(Availability):服务A、B、C三个节点,其中一个节点宕机不影响整个集群对外服务,如果只服务与一个服务器,只要这个服务宕机,必然会导致无法提供的问题。
    分区容忍性(Partition Tolerance):分区容忍性就是允许系统通过网络协同工作。分区容忍性要解决由于网络分区导致数据的不完整及无法访问等问题。

    分布式系统不可避免的出现了多个系统通过网络协同工作的场景,结点之间难免会出现网络中断、网延延迟等现象,这种现象一旦出现就导致数据被分散在不同的结点上,这就是网络分区

    分布式系统能否兼容C、A、P?

    在保证分区容忍性的前提下一致性和可用性是无法兼容的,要提高系统的可用性就需要增加更多的节点,但是节点多系统的一致性就差,因此分布式系统是无法同时保证,一致性、可用性、分区容忍性这个是不可能做到的。
    CAP有哪些组合?
    1.CA:一致性+高可用,
    2.AP:高可用+分区容忍性,追求的是最终一致性,
    说明:这里放弃一致性是指放弃强一致性,强一致性就是写入成功立刻要查询出最新数据。追求最终一致性是指允许暂时的数据不一致,只要最终在用户接受的时间内数据 一致即可
    3.CP:放弃可用性,加强一致性和分区容忍性,一些强一致性要求的系统按CP进行设计,比如跨行转账,一次转账请求要等待双方银行系统都完成整个事务才算完成。
    说明:由于网络问题的存在CP系统可能会出现待等待超时,如果没有处理超时问题则整理系统会出现阻塞
    总结:​ 在分布式系统设计中AP的应用较多,即保证分区容忍性和可用性,牺牲数据的强一致性(写操作后立刻读取到最新数据),保证数据最终一致性。比如:订单退款,今日退款成功,明日账户到账,只要在预定的用户可以接受的时间内退款事务走完即可。

    4.分布式事务的解决方案

    两阶段提交协议(2PC)
    为解决分布式系统的数据一致性问题出现了两阶段提交协议(2 Phase Commitment Protocol),两阶段提交由协调者和参与者组成,共经过两个阶段和三个操作,部分关系数据库如Oracle、MySQL支持两阶段提交协议。
    第一阶段:准备阶段
    协调者通知参与者准备提交订单,参与者开始投票,参与者完成协调工作向协调者发出yes,
    第二阶段:提交和回滚阶段
    协调者完成准备工作后发出提交指令。如果出现问题就立马进程回滚操作;
    在这里插入图片描述
    1.协调者(应用服务器),连接两台数据库
    2.协调者向两台服务器发出准备工作,二台数据库接受到准备的指令(执行本地事务),但是不提交,向协调者发出yes,如果都收得到yes,则执行提交事件,如果一个数据源发出no的指令,立马执行回滚操作。
    2PC优点:执行强一致 部分关系数据库支持(Oracle、MySQL等)。(CP)
    缺点:整个事务的执行需要由协调者在多个节点之间去协调,增加了事务的执行时间,性能低下。

    事务补偿(TCC)
    TCC事务弥补是基于2PC实现业务层事务控制方案,TCC由try,confirm,cancel 三部分组成
    1:try检查以及预留业务资源完成提交事务前的检查,预留好资源
    2:confirm确定执行业务操作,对try预留的资源进行正式执行
    3:cancel取消执行业务操作,并且对try的资源进行回滚
    在这里插入图片描述
    1、Try
    下单业务由订单服务和库存服务协同完成,在try阶段订单服务和库存服务完成检查和预留资源。
    订单服务检查当前是否满足提交订单的条件(比如:当前存在未完成订单的不允许提交新订单)。
    库存服务检查当前是否有充足的库存,并锁定资源。
    2、Confirm
    订单服务和库存服务成功完成Try后开始正式执行资源操作。
    订单服务向订单写一条订单信息。
    库存服务减去库存。
    3、Cancel
    如果订单服务和库存服务有一方出现失败则全部取消操作。
    订单服务需要删除新增的订单信息。
    库存服务将减去的库存再还原。
    优点:最终保证数据的一致性,在业务层实现事务控制,灵活性好。(AP)
    缺点:开发成本高,每个事务操作每个参与者都需要实现try/confirm/cancel三个接口。
    注意:TCC的try/confirm/cancel接口都要实现幂等性,在为在try、confirm、cancel失败后要不断重试。

    什么是幂等性?

    幂等性是指一个操作无论请求多少次,执行结果都一样
    幂等性实现方式:
    一,操作前在业务方法进行判断如果执行了就不再执行
    二,缓存所有请求和处理的结果,已经处理的请求则直接返回结果。
    三,在数据库表中加一个状态字段(未处理,已处理),数据操作时判断未处理时再处理。

    消息队列实现最终一致

    将分布式事务拆分成多个本地事务来完成,并且由消息队列异步协调完成
    在这里插入图片描述
    1、订单服务和库存服务完成检查和预留资源。
    2、订单服务在本地事务中添加订单记录和添加减少库存的信息
    3、定时任务会根据消息表中的记录将消息发送到MQ中异步通知库存服务减少库存
    4、库存服务执行减少库存信息,并且记录减少库存信息的记录日志,
    5、库存服务向MQ发送减少库存信息
    6、订单服务接收到完成库存减少的消息后删除原来添加的“减少库存任务消息”。
    实现最终事务一致要求:预留资源成功理论上要求正式执行成功,如果执行失败会进行重试,要求业务执行方法实现幂等
    优点 :
    由MQ按异步的方式协调完成事务,性能较高。
    不用实现try/confirm/cancel接口,开发成本比TCC低。
    缺点:
    此方式基于关系数据库本地事务来实现,会出现频繁读写数据库记录,浪费数据库资源,另外对于高并发操作不是最佳方案

    展开全文
  • 目录 1.分布式事务基础理论 1.1.CAP理论 1.2.BASE理论 2.分布式事务解决方案之2PC(两阶段提交) ...因此,分布式事务需要更进一步的理论支持,接下来,我们先来学习一下分布式事务的CAP理论。 1.1.CAP理论 C..

     

    目录

    1.分布式事务基础理论

    1.1.CAP理论

    1.2.BASE理论

    2.分布式事务解决方案之2PC(两阶段提交) 

    2.2.1 XA方案

    2.2.2 Seata方案

    2.2.3分布式事务解决方案之TCC 


    源码地址:https://github.com/kaixuanzhang123/dtx.git

    1.分布式事务基础理论

    我们了解到了分布式事务的基础概念。与本地事务不同的是,分布式系统之所以叫分布式,是因为提供服务的各个节点分布在不同机器上,相互之间通过网络交互。不能因为有一点网络问题就导致整个系统无法提供服务,网络因素成为了分布式事务的考量标准之一。因此,分布式事务需要更进一步的理论支持,接下来,我们先来学习一下分布式事务的CAP理论。

    1.1.CAP理论

    CAP是 Consistency、Availability、Partition tolerance三个词语的缩写,分别表示一致性、可用性、分区容忍性。

    1.2.BASE理论

     1、理解强一致性和最终一致性

     CAP理论告诉我们一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容忍性(Partition tolerance)这三项中的两项,其中AP在实际应用中较多,AP即舍弃一致性,保证可用性和分区容忍性,但是在实际生产中很多场景都要实现一致性,比如前边我们举的例子主数据库向从数据库同步数据,即使不要一致性,但是最终也要将数据同步成功来保证数据一致,这种一致性和CAP中的一致性不同,CAP中的一致性要求在任何时间查询每个结点数据都必须一致,它强调的是强一致性,但是最终一致性是允许可以在一段时间内每个结点的数据不一致,但是经过一段时间每个结点的数据必须一致,它强调的是最终数据的一致性。

     2、Base理论介绍

     BASE 是 Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent (最终一致性)三个短语的缩写。BASE理论是对CAP中AP的一个扩展,通过牺牲强一致性来获得可用性,当出现故障允许部分不可用但要保证核心功能可用,允许数据在一段时间内是不一致的,但最终达到一致状态。满足BASE理论的事务,我们称之为“柔性事务”。

    2.分布式事务解决方案之2PC(两阶段提交) 

    前面已经学习了分布式事务的基础理论,以理论为基础,针对不同的分布式场景业界常见的解决方案有2PC、TCC、可靠消息最终一致性、最大努力通知这几种。

    2.1.什么是2PC
        2PC即两阶段提交协议,是将整个事务流程分为两个阶段,准备阶段(Prepare phase)、提交阶段(commitphase),2是指两个阶段,P是指准备阶段,C是指提交阶段。
    举例:张三和李四好久不见,老友约起聚餐,饭店老板要求先买单,才能出票。这时张三和李四分别抱怨近况不如意,囊中羞涩,都不愿意请客,这时只能AA。只有张三和李四都付款,老板才能出票安排就餐。但由于张三和李四都是铁公鸡,形成了尴尬的一幕:
        准备阶段:老板要求张三付款,张三付款。老板要求李四付款,李四付款。
        提交阶段:老板出票,两人拿票纷纷落座就餐。
        例子中形成了一个事务,若张三或李四其中一人拒绝付款,或钱不够,店老板都不会给出票,并且会把已收款退回。整个事务过程由事务管理器和参与者组成,店老板就是事务管理器,张三、李四就是事务参与者,事务管理器负责决策整个分布式事务的提交和回滚,事务参与者负责自己本地事务的提交和回滚。
    在计算机中部分关系数据库如Oracle、MySQL支持两阶段提交协议,如下图:
        1. 准备阶段(Prepare phase):事务管理器给每个参与者发送Prepare消息,每个数据库参与者在本地执行事务,并写本地的Undo/Redo日志,此时事务没有提交。(Undo日志是记录修改前的数据,用于数据库回滚,Redo日志是记录修改后的数据,用于提交事务后写入数据文件)
        2. 提交阶段(commit phase):如果事务管理器收到了参与者的执行失败或者超时消息时,直接给每个参与者发送回滚(Rollback)消息;否则,发送提交(Commit)消息;参与者根据事务管理器的指令执行提交或者回滚操作,并释放事务处理过程中使用的锁资源。注意:必须在最后阶段释放锁资源。
    下图展示了2PC的两个阶段,分成功和失败两个情况说明:
       成功情况:

        

      失败情况:

        

    2.2.1 XA方案

        2PC的传统方案是在数据库层面实现的,如Oracle、MySQL都支持2PC协议,为了统一标准减少行业内不必要的对接成本,需要制定标准化的处理模型及接口标准,国际开放标准组织Open Group定义了分布式事务处理模型DTP(Distributed Transaction Processing Reference Model)。为了让大家更明确XA方案的内容程,下面新用户注册送积分为例来说明:

                       

    执行流程如下:
      1、应用程序(AP)持有用户库和积分库两个数据源。
      2、应用程序(AP)通过TM通知用户库RM新增用户,同时通知积分库RM为该用户新增积分,RM此时并未提交事务,此时用户和积分资源锁定。
      3、TM收到执行回复,只要有一方失败则分别向其他RM发起回滚事务,回滚完毕,资源锁释放。
      4、TM收到执行回复,全部成功,此时向所有RM发起提交事务,提交完毕,资源锁释放。
    DTP模型定义如下角色:
        AP(Application Program):即应用程序,可以理解为使用DTP分布式事务的程序。
        RM(Resource Manager):即资源管理器,可以理解为事务的参与者,一般情况下是指一个数据库实例,通过资源管理器对该数据库进行控制,资源管理器控制着分支事务。
       TM(Transaction Manager):事务管理器,负责协调和管理事务,事务管理器控制着全局事务,管理事务生命周期,并协调各个RM。全局事务是指分布式事务处理环境中,需要操作多个数据库共同完成一个工作,这个工作即是一个全局事务。
       DTP模型定义TM和RM之间通讯的接口规范叫XA,简单理解为数据库提供的2PC接口协议,基于数据库的XA
       协议来实现2PC又称为XA方案。
      以上三个角色之间的交互方式如下:
        1)TM向AP提供 应用程序编程接口,AP通过TM提交及回滚事务。
        2)TM交易中间件通过XA接口来通知RM数据库事务的开始、结束以及提交、回滚等。
    总结:
      整个2PC的事务流程涉及到三个角色AP、RM、TM。AP指的是使用2PC分布式事务的应用程序;RM指的是资源管理器,它控制着分支事务;TM指的是事务管理器,它控制着整个全局事务。

     XA方案的问题:
      1、需要本地数据库支持XA协议。
      2、资源锁需要等到两个阶段结束才释放,性能较差。

    2.2.2 Seata方案

      Seata的设计目标其一是对业务无侵入,因此从业务无侵入的2PC方案着手,在传统2PC的基础上演进,并解决2PC方案面临的问题。
      Seata把一个分布式事务理解成一个包含了若干分支事务的全局事务。全局事务的职责是协调其下管辖的分支事务达成一致,要么一起成功提交,要么一起失败回滚。此外,通常分支事务本身就是一个关系数据库的本地事务,下图是全局事务与分支事务的关系图:

       

    还拿新用户注册送积分举例Seata的分布式事务过程: 

       

    具体的执行流程如下:
      1. 用户服务的 TM 向 TC 申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的XID。
      2. 用户服务的 RM 向 TC 注册 分支事务,该分支事务在用户服务执行新增用户逻辑,并将其纳入 XID 对应全局事务的管辖。
      3. 用户服务执行分支事务,向用户表插入一条记录。
      4. 逻辑执行到远程调用积分服务时(XID 在微服务调用链路的上下文中传播)。积分服务的RM 向 TC 注册分支事务,该分支事务执行增加积分的逻辑,并将其纳入 XID 对应全局事务的管辖。
      5. 积分服务执行分支事务,向积分记录表插入一条记录,执行完毕后,返回用户服务。
      6. 用户服务分支事务执行完毕。
      7. TM 向 TC 发起针对 XID 的全局提交或回滚决议。
      8. TC 调度 XID 下管辖的全部分支事务完成提交或回滚请求。
    Seata实现2PC与传统2PC的差别:
       架构层次方面,传统2PC方案的 RM 实际上是在数据库层,RM 本质上就是数据库自身,通过 XA 协议实现,而Seata的 RM 是以jar包的形式作为中间件层部署在应用程序这一侧的。两阶段提交方面,传统2PC无论第二阶段的决议是commit还是rollback,事务性资源的锁都要保持到Phase2完成才释放。而Seata的做法是在Phase1 就将本地事务提交,这样就可以省去Phase2持锁的时间,整体提高效率。

    2.2.3分布式事务解决方案之TCC 

        TCC是Try、Confirm、Cancel三个词语的缩写,TCC要求每个分支事务实现三个操作:预处理Try、确认Confirm、撤销Cancel。Try操作做业务检查及资源预留,Confirm做业务确认操作,Cancel实现一个与Try相反的操作即回滚操作。TM首先发起所有的分支事务的try操作,任何一个分支事务的try操作执行失败,TM将会发起所有分支事务的Cancel操作,若try操作全部成功,TM将会发起所有分支事务的Confirm操作,其中Confirm/Cancel操作若执行失败,TM会进行重试。 

      TCC分为三个阶段:
        1. Try 阶段是做业务检查(一致性)及资源预留(隔离),此阶段仅是一个初步操作,它和后续的Confirm 一起才能真正构成一个完整的业务逻辑。
        2. Confirm 阶段是做确认提交,Try阶段所有分支事务执行成功后开始执行 Confirm。通常情况下,采用TCC则认为 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。若Confirm阶段真的出错了,需引入重试机制或人工处理。
        3. Cancel 阶段是在业务执行错误需要回滚的状态下执行分支事务的业务取消,预留资源释放。通常情况下,采用TCC则认为Cancel阶段也是一定成功的。若Cancel阶段真的出错了,需引入重试机制或人工处理。
        4. TM事务管理器
        TM事务管理器可以实现为独立的服务,也可以让全局事务发起方充当TM的角色,TM独立出来是为了成为公用组件,是为了考虑系统结构和软件复用。TM在发起全局事务时生成全局事务记录,全局事务ID贯穿整个分布式事务调用链条,用来记录事务上下文,追踪和记录状态,由于Confirm 和cancel失败需进行重试,因此需要实现为幂等,幂等性是指同一个操作无论请求多少次,其结果都相同。 

    TCC需要注意三种异常处理分别是空回滚、幂等、悬挂:
      空回滚:
        在没有调用 TCC 资源 Try 方法的情况下,调用了二阶段的 Cancel 方法,Cancel 方法需要识别出这是一个空回滚,然后直接返回成功。出现原因是当一个分支事务所在服务宕机或网络异常,分支事务调用记录为失败,这个时候其实是没有执行Try阶段,当故障恢复后,分布式事务进行回滚则会调用二阶段的Cancel方法,从而形成空回滚。解决思路是关键就是要识别出这个空回滚。思路很简单就是需要知道一阶段是否执行,如果执行了,那就是正常回滚;如果没执行,那就是空回滚。前面已经说过TM在发起全局事务时生成全局事务记录,全局事务ID贯穿整个分布式事务调用链条。再额外增加一张分支事务记录表,其中有全局事务 ID 和分支事务 ID,第一阶段 Try 方法里会插入一条记录,表示一阶段执行了。Cancel 接口里读取该记录,如果该记录存在,则正常回滚;如果该记录不存在,则是空回滚。
      幂等:
        通过前面介绍已经了解到,为了保证TCC二阶段提交重试机制不会引发数据不一致,要求 TCC 的二阶段 Try、Confirm 和 Cancel 接口保证幂等,这样不会重复使用或者释放资源。如果幂等控制没有做好,很有可能导致数据不一致等严重问题。解决思路在上述“分支事务记录”中增加执行状态,每次执行前都查询该状态。
      悬挂:
        悬挂就是对于一个分布式事务,其二阶段 Cancel 接口比 Try 接口先执行。出现原因是在 RPC 调用分支事务try时,先注册分支事务,再执行RPC调用,如果此时 RPC 调用的网络发生拥堵,通常 RPC 调用是有超时时间的,RPC 超时以后,TM就会通知RM回滚该分布式事务,可能回滚完成后,RPC 请求才到达参与者真正执行,而一个 Try 方法预留的业务资源,只有该分布式事务才能使用,该分布式事务第一阶段预留的业务资源就再也没有人能够处理了,对于这种情况,我们就称为悬挂,即业务资源预留后没法继续处理。解决思路是如果二阶段执行完成,那一阶段就不能再继续执行。在执行一阶段事务时判断在该全局事务下,“分支事务记录”表中是否已经有二阶段事务记录,如果有则不执行Try。

    举例,场景为 A 转账 30 元给 B,A和B账户在不同的服务。
      方案1:
      账户A

    try:
    检查余额是否够30元    
    扣减30元    
       
    confirm:
    空    
    cancel:
    增加30元 

      账户B

    try:
    增加30元    
    confirm:
    空    
    cancel:
    减少30元 

      方案1说明:
        1)账户A,这里的余额就是所谓的业务资源,按照前面提到的原则,在第一阶段需要检查并预留业务资源,因此,我们在扣钱 TCC 资源的 Try 接口里先检查 A 账户余额是否足够,如果足够则扣除 30 元。 Confirm 接口表示正式提交,由于业务资源已经在 Try 接口里扣除掉了,那么在第二阶段的 Confirm 接口里可以什么都不用做。Cancel接口的执行表示整个事务回滚,账户A回滚则需要把 Try 接口里扣除掉的 30 元还给账户。
        2)账号B,在第一阶段 Try 接口里实现给账户B加钱,Cancel 接口的执行表示整个事务回滚,账户B回滚则需要把Try 接口里加的 30 元再减去。
      方案1的问题分析:
        1)如果账户A的try没有执行在cancel则就多加了30元。
        2)由于try,cancel、confirm都是由单独的线程去调用,且会出现重复调用,所以都需要实现幂等。
        3)账号B在try中增加30元,当try执行完成后可能会其它线程给消费了。
        4)如果账户B的try没有执行在cancel则就多减了30元。

      问题解决:
        1)账户A的cancel方法需要判断try方法是否执行,正常执行try后方可执行cancel。
        2)try,cancel、confirm方法实现幂等。
        3)账号B在try方法中不允许更新账户金额,在confirm中更新账户金额。
        4)账户B的cancel方法需要判断try方法是否执行,正常执行try后方可执行cancel。

      优化方案:

      账户A

    try:
    try幂等校验    
    try悬挂处理    
    检查余额是否够30元    
    扣减30元    
    confirm:
    空    
    cancel:
    cancel幂等校验    
    cancel空回滚处理    
    增加可用余额30元 

      账户B

    try:
    空    
    confirm:
    confirm幂等校验    
    正式增加30元    
    cancel:
    空  

                                           欢迎关注我的公众号,一起学习!

                                

                       关注「Java源码进阶」,获取海量java,大数据,机器学习资料!

    展开全文
  • NULL 博文链接:https://leesonhomme.iteye.com/blog/525677
  • java分布式事务.docx

    2021-06-27 14:29:32
    分布式事务文档详解
  • JAVA 分布式事务框架Atomikos爬坑日记

    千次阅读 2018-09-14 16:41:03
    由于有一天,脑子蛋疼想了下用了分布式事务该怎么办??(真的是为了自己一个蛋疼的想法而研究学习的) 于是勤学苦问(真的是勤学苦问啊,百度了不下500页吧,终于找到好的解决方案,并且测试成功,花了我24个...
  • Redis作Java分布式锁  我们都知道redis现在成为越来越多人作为缓存工具的选择,redis在性能、操作等方面上有着独特的优势。 1. 检查reids版本   因为redis是在2.6版本后才内置了Lua脚本解释器,所以也就是说要用...
  • 参与事务的应用程序都应该提供三个http接口,由一个事务协调者进行整体事务的协调" Try接口:预留业务资源;跟普通的操作操作差不多,只是有个status来标识为预生效; Confirm接口:确认执行业务操作;update ...
  • 高级JAVA开发 分布式事务部分

    千次阅读 2020-07-04 18:03:51
    高级JAVA开发 分布式事务部分『分布式事务』中的相关概念2PC(Two Phase Commitment Protocol)XATCC3PC 参考和摘自: 分布式事务的4种模式 『分布式事务』中的相关概念 2PC(Two Phase Commitment Protocol) 2PC是...
  • 分布式事务视频教程

    2017-12-26 14:59:43
    微服务架构的分布式事务解决方案(附课件),完整版。附件是 txt 文件,内含网盘地址
  • 1、什么是分布式事务 分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。以上是百度百科的解释,简单的说,就是一次大的操作由不同的小操作组成,...
  • java实现分布式事务的三种方案

    千次阅读 2019-10-20 23:50:51
    问题描述: 用户支付完成会将支付状态及订单...的关键是如何保证两个分布式服务的事务的一致性。 尝试解决上边的需求,在订单服务中远程调用减库存接口,伪代码如下: 订单支付结果通知方法{ ​ 更新支付表中...
  • 分布式事务基本理论 基本概念 通常把一个数据库内部的事务处理,如对多个表的操作,作为本地事务看待。数据库的事务处理对象是本地事务,而分布式事务处理的对象是全局事务。 所谓全局事务,是指分布式事务处理环境...
  • java分布式事务

    千次阅读 2016-10-10 17:30:13
    在本系列先前的文章中,我们主要讲解了JDBC对本地事务的处理,本篇文章将讲到一个分布式事务的例子。    请通过以下方式下载github源代码: git clone ...
  • java 什么是分布式事务?如何面对高并发,处理分布式事务。。。。。。。。。。。。
  • Java微服务下的分布式事务介绍及其解决方案

    万次阅读 多人点赞 2019-03-22 15:48:46
    1.前言 ...这就很尴尬了,当然微服务下可能没有分布式事务,但是很多场景是需要分布式事务的,下面我就来介绍下什么是分布式事务,和分布式事务的解决方案 2 问题描述 在介绍分布式事务...
  • java事务和分布式事务详解

    千次阅读 2018-11-06 23:18:14
    面试经常会问到分布式锁、分布式事务、SOA 服务化、分布式系统等业务、架构的问题和解决方案,工作中接触的业务方面事关金融,也需要解决一些类似的业务问题,所以总结了一篇浅谈分享,后面实战篇正在准备,这几周会...
  • JAVA分布式事务原理及应用(转)

    千次阅读 2016-03-01 15:23:34
    JAVA分布式事务原理及应用(转) 引言  JTA(Java Transaction API)允许应用程序执行分布式事务处理--在两个或多个网络计算机资源上访问并且更新数据。JDBC驱动程序的JTA支持极大地增强了数据访问能力。  ...
  • 今天讲一讲面试当中经常说到的分布式事务的一些解决方案,供大家参考。 分布式事务了解吗? 你们是如何解决分布式事务问题的? 只要聊到你做了分布式系统,必问分布式事务,你对分布式事务一无所知的话,确实会很...
  • java事务和分布式事务

    千次阅读 2018-11-06 23:30:13
    3 spring事务架构transaction模块 3 spring事务架构transaction模块 1 事务管理PlatformTransactionManager的架构 Springboot内部提供的事务管理器是根据autoconfigure来进行决定的。 比如当使用jpa的时候,...
  • Java微服务下的分布式事务介绍及其解决方案2

    万次阅读 多人点赞 2019-03-22 16:53:42
    本文将详细介绍分布式的解决方案–消息队列实现分布式事务的解决方案,需要大家对我第一篇对分布式事务的介绍来了解下,会更清楚一点哦,第一篇博客的地址分布式事务的介绍 2.业务场景介绍 我们模拟慕课网付费...
  • Java分布式事务(JTA和XA)

    千次阅读 2019-06-13 16:45:25
    何为分布式事务 一个事务包含多个操作,多个操作操作了多个数据源,这样的事务称为分布式事务。 案例 为什么不能简单的借助数据源的本地事务 用数据源本地事务代码案例 Con1 = db1.getConn..; Con2 = db2.getConn.....
  • SSH + atomikos 打造Java分布式事务 web工程 直接导入myeclipse即可运行 数据库可参照mutilDataSource/model下的实体类进行创建(两个表)数据库使用的是oracle
  • rabbitmq分布式事务

    2020-12-01 18:14:00
    基于rabbit和本地消息表实现可靠消息一致性分布式事务,项目下载下来直接可以用了,已经包含了配置文件和数据库脚本,有问题的可以给我私信。项目架构springboot、nacos、rabbitMq、redis、MySQL
  • 分布式事务区别于本地事务,是指事务的操作位于不同的节点上,需要保证事务的 AICD 特性。常见的分布式事务场景:跨银行转操作就涉及调用两个异地银行服务。 目录 一、两阶段提交(2PC) 1、两阶段 2、具体流程 ...
  • 分布式事务1.分布式事务是什么?2.什么时候使用分布式事务3.分布式事务常见解决方案3.1 基于 XA 协议的两阶段提交3.2 消息事务+最终一致性 1.分布式事务是什么? 在分布式系统中,事务参与者在不同的分布式节点上或...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 157,804
精华内容 63,121
关键字:

java分布式事务

java 订阅