• 以银行转账为例分析分布式事务的解决方案


    提起分布式系统,就会涉及分布式事务,本文就以金融项目的转账业务为例,分析各种业务场景下的转账业务的事物问题。
     
    一、业务场景
    以工商银行转账业务为例,那么项目的分布式架构大致如下,一个银行的一个支行部署一个节点,那么相同节点之间的业务就是本地事务、不同节点之间的就是分布式事务
    转账业务包括以下三种情况
    支行内转账:同为工行的相同支行内转账(本地事务)
    行内转账:同为工行的非同支行内转账 (分布式事务)
    跨行转账:和其他银行的系统进行转账 (分布式事务)
     
    1.1、支行内转账业务
    如用户A和用户B都是工行-杭州支行的用户,A向B转账10000元,那么就需要保证事务,从而达到A的账户-10000,而B的账户+10000的效果
    由于是本地事务,所以A账户的扣减和B账户的增加就可以放在一个事务中实现,基本上没有太大的问题,不管哪一步异常了都可以实现事务回滚。
     
    1.2、行内转账
    如用户A是杭州支行,用户B是北京支行,A向B转账10000元,那么虽然都是工行用户,但是是分布式部署的,就会涉及到跨库的分布式事务问题,一般解决方案有同步和异步两种方式:
    同步方式可以如下:
    1、创建转账订单,订单状态为待成功
    2、用户A扣减10000元
    3、发起转账请求到北京支行
    4、北京支行创建转账订单,订单状态为待成功
    5、用户B增加10000元
    6、北京支行订单状态改为成功并返回结果
    7、杭州支行接收响应结果,如果为成功则提交事务表示转账成功,如果为失败则更新订单状态为转账失败
    8、定时任务根据查询转账失败订单在北京支行的订单订单状态,如果失败,则回滚转账事务;如果成功则提交事务
     
    异步方式如下:
    1、创建转账订单
    2、用户A冻结10000元
    3、提交事务
    4、异步发起转账请求,判断结果
    结果可以为:
    1、转账成功:确认成功
    2、转账失败:确认失败
    3、请求异常:结果不确认
     
    对于结果不确定的情况就采用:查询的方式查询结果,查询结果还是不确定的话
    就采用定时任务查询异常订单查询
     
    1.3、跨行转账
    如用户A是工行用户,用户B是建行用户,A向B转账10000元,这里两个用户不是同一个行的用户,基本上就不会再采用同步的方式进行转账了。
    异步方式如下:
    1、创建转账订单,订单状态为待成功
    2、用户A冻结10000元
    3、提交事务
    这里需要保证的是用户资金和订单状态的事务
    异步发送http请求到其他行进行转账业务,
    结果可以为:
    1、转账成功:确认成功
    2、转账失败:确认失败
    3、请求异常:结果不确认
     
    对于结果不确定的情况就采用:查询的方式查询结果,查询结果还是不确定的话
    就采用定时任务查询异常订单查询
     
     
    金融项目一般不会太重视转账的实时性,而是重视转账的一致性,比较涉及到的是金钱,所以必须要确保转账的事务性。
    总体来说,解决转账的分布式事务还是以异步为主,采用的是最终一致性来解决分布式事务问题。大致流程如下:
    1、事务1执行事务,并创建订单,确保订单和金额变得的一致性
    2、异步发起转账请求
    3、接收异步回调或同步响应
    4、如果是成功则更新订单状态和金额、如果是失败则回滚、如果是不确定则通过查询的方式来确认订单的结果
    5、根据订单的最终结果来更新数据
     
    二、其他分布式事务解决方案
     
    2.1、基于XA的二阶段提交协议
    基于二阶段提交的方案主要是将事务分成了两个阶段,一个是事务准备阶段,一个是事务提交阶段,并且需要一个事务管理者的角色,也就是事务管理器
    第一阶段:
    1、事务管理器通知所有参与事务的各个本地资源管理器,通知他们准备事务
    2、各个本地资源管理器进行事务准备,写好事务日志并执行事务,但是不提交,然后将本地事务执行的结果上报给事务管理器
     
    第二阶段:
    1、事务管理器接收各个本地资源管理器执行的事务结果,如果全部成功则表示事务成功,需要提交;如果有一个失败则表示事务失败,需要回滚
    2、事务管理器向各个资源管理器发生提交或回滚请求,各个资源管理器分别进行提交或回滚(提交或回滚的耗时很短,失败的概率相对很低)
     
     
    2.2、TCC方案
    TCC方案是将事务分成了三个阶段,分别是try、commit、callback阶段。
     
    事务开始时,业务应用会向事务协调器注册启动事务。之后业务应用会调用所有服务的try接口,完成一阶段准备。之后事务协调器会根据try接口返回情况,决定调用confirm接口或者cancel接口。如果接口调用失败,会进行重试。
    TCC方案让应用自己定义数据库操作的粒度,使得降低锁冲突、提高吞吐量成为可能。 当然TCC方案也有不足之处,集中表现在以下两个方面:
    • 对应用的侵入性强。业务逻辑的每个分支都需要实现try、confirm、cancel三个操作,应用侵入性较强,改造成本高。
    • 实现难度较大。需要按照网络状态、系统故障等不同的失败原因实现不同的回滚策略。为了满足一致性的要求,confirm和cancel接口必须实现幂等。
    上述原因导致TCC方案大多被研发实力较强、有迫切需求的大公司所采用。微服务倡导服务的轻量化、易部署,而TCC方案中很多事务的处理逻辑需要应用自己编码实现,复杂且开发量大。
     
    2.3、基于MQ的最终一致性
    基于MQ的一致性相当于是异步实现的分布式事务,将事务分成了两个不关联的本地事务,基于MQ进行同步,根据最终结果实现一致性从而达到分布式事务
     
    2.4、基于fescar实现的分布式事务

    XA的第一阶段是执行sql,但是不提交,第二阶段一起提交 (会导致锁的时间是整个事务的时间)
    Fescar的第一阶段是各个分支事务执行并提交事务,只是在提交之前持久化了回滚日志(undo log),第二阶段如果是提交的话就只需要删除持久化日志即可;否则才需要执行回滚操作
    主要是对XA的优化,第一阶段的区别
     
     
     
  • 相关阅读:
    Haproxy+Keepalived高可用环境部署梳理(主主和主从模式)
    使用nginx sticky实现基于cookie的负载均衡
    CENTOS 6.6初始化SHELL脚本
    Java 开源博客 Solo 1.2.0 发布
    Java 开源博客 Solo 1.2.0 发布
    Java多线程-synchronized关键字
    Maven项目pom.xml配置详解
    4.0 苹果系统安装之黑苹果(4)
    3.0 Windows和Linux双系统安装(3)
    2.0 Linux系统的安装之Fedora安装单系统(2)
  • 原文地址:https://www.cnblogs.com/jackion5/p/11364935.html
Copyright © 2020-2023  润新知