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

摘要:
提起分布式系统,就会涉及分布式事务,本文就以金融项目的转账业务为例,分析各种业务场景下的转账业务的事物问题。总体来说,解决转账的分布式事务还是以异步为主,采用的是最终一致性来解决分布式事务问题。
提起分布式系统,就会涉及分布式事务,本文就以金融项目的转账业务为例,分析各种业务场景下的转账业务的事物问题。
一、业务场景
以工商银行转账业务为例,那么项目的分布式架构大致如下,一个银行的一个支行部署一个节点,那么相同节点之间的业务就是本地事务、不同节点之间的就是分布式事务
转账业务包括以下三种情况
支行内转账:同为工行的相同支行内转账(本地事务)
行内转账:同为工行的非同支行内转账 (分布式事务)
跨行转账:和其他银行的系统进行转账 (分布式事务)
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张
第一阶段:
1、事务管理器通知所有参与事务的各个本地资源管理器,通知他们准备事务
2、各个本地资源管理器进行事务准备,写好事务日志并执行事务,但是不提交,然后将本地事务执行的结果上报给事务管理器
第二阶段:
1、事务管理器接收各个本地资源管理器执行的事务结果,如果全部成功则表示事务成功,需要提交;如果有一个失败则表示事务失败,需要回滚
2、事务管理器向各个资源管理器发生提交或回滚请求,各个资源管理器分别进行提交或回滚(提交或回滚的耗时很短,失败的概率相对很低)
2.2、TCC方案
TCC方案是将事务分成了三个阶段,分别是try、commit、callback阶段。
以银行转账为例分析分布式事务的解决方案第2张
事务开始时,业务应用会向事务协调器注册启动事务。之后业务应用会调用所有服务的try接口,完成一阶段准备。之后事务协调器会根据try接口返回情况,决定调用confirm接口或者cancel接口。如果接口调用失败,会进行重试。
TCC方案让应用自己定义数据库操作的粒度,使得降低锁冲突、提高吞吐量成为可能。 当然TCC方案也有不足之处,集中表现在以下两个方面:
  • 对应用的侵入性强。业务逻辑的每个分支都需要实现try、confirm、cancel三个操作,应用侵入性较强,改造成本高。
  • 实现难度较大。需要按照网络状态、系统故障等不同的失败原因实现不同的回滚策略。为了满足一致性的要求,confirm和cancel接口必须实现幂等。
上述原因导致TCC方案大多被研发实力较强、有迫切需求的大公司所采用。微服务倡导服务的轻量化、易部署,而TCC方案中很多事务的处理逻辑需要应用自己编码实现,复杂且开发量大。
2.3、基于MQ的最终一致性
以银行转账为例分析分布式事务的解决方案第3张
基于MQ的一致性相当于是异步实现的分布式事务,将事务分成了两个不关联的本地事务,基于MQ进行同步,根据最终结果实现一致性从而达到分布式事务
2.4、基于fescar实现的分布式事务
以银行转账为例分析分布式事务的解决方案第4张

XA的第一阶段是执行sql,但是不提交,第二阶段一起提交 (会导致锁的时间是整个事务的时间)
Fescar的第一阶段是各个分支事务执行并提交事务,只是在提交之前持久化了回滚日志(undo log),第二阶段如果是提交的话就只需要删除持久化日志即可;否则才需要执行回滚操作
主要是对XA的优化,第一阶段的区别

免责声明:文章转载自《以银行转账为例分析分布式事务的解决方案》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇用C#搭建IE BHO勾子, 取表单密码java安全沙箱(四)之安全管理器及Java API下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

SQL SERVER的锁机制(三)——概述(锁与事务隔离级别)

五、锁与事务隔离级别 事务隔离级别简单的说,就是当激活事务时,控制事务内因SQL语句产生的锁定需要保留多入,影响范围多大,以防止多人访问时,在事务内发生数据查询的错误。设置事务隔离级别将影响整条连接。 SQL Server 数据库引擎支持所有这些隔离级别: · 未提交读(隔离事务的最低级别,只能保证不读取物理上损坏的数据) · 已提交读(数据库引擎的默认级...

vertica在电信的应用

本文介绍了什么 ´电信级大数据分析典型需求 ´Vertica数据库特点及与其他数据库对比 ´Vertica核心技术介绍 ´基于Vertica的典型分系统架构简介 电信级大数据分析典型需求´海量数据存储:年分析数据量达到PB级 Counter数据:各网元收集的统计数据,可用于监控和测量网络性能 MR详单:即手机向网络上报的无线性能测量报告,反映了用户实时...

MySQL的WAL(WriteAhead Logging)机制

MySQL 里经常说到的 WAL技术,也就是先写日志,再写磁盘。 当内存数据页跟磁盘数据页内容不一致的时候,我们成这个内存页为“脏页”。内存数据写入磁盘后,内存和磁盘上的数据页内容就一致了,称为“干净页”。 MySQL 从 内存更新到磁盘的过程,称为刷脏页的过程(flush)。 InnoDB 刷脏页的时机: 内存中的redo log 写满了,这时系统...

ADO.NET事务处理

一 事务处理介绍 事务是这样一种机制,它确保多个SQL语句被当作单个工作单 元来处理。事务具有以下的作用: * 一致性:同时进行的查询和更新彼此不会发生冲突,其他 用户不会看到发生了变化但尚未提交的数据。 * 可恢复性:一旦系统故障,数据库会自动地完全恢复未完 成的事务。 二 事务与一致性 事务是完整性的单位,一个事务的执行是把数据库从一个一 致的状态转...

【转】Java类加载原理解析

原链接 1 基本信息 每个java开发人员对java.lang.ClassNotFoundExcetpion这个异常肯定都不陌生,这背后就涉及到了java技术体系中的类加载。 Java的类加载机制是java技术体系中比较核心的部分,虽然和大部分开发人员直接打交道不多, 但是对其背后的机理有一定理解有助于排查程序中出现的类加载失败等技术问题,对理解java虚...

IIS日志-网站运维的好帮手

感谢原博主!原博客地址:http://www.cnblogs.com/fish-li/p/3139366.html 对于一个需要长期维护的网站来说,如何让网站长久稳定运行是件很有意义的事情。 有些在开发阶段没有暴露的问题很有可能就在运维阶段出现了,这也是很正常的。 还有些时候,我们希望不断地优化网站,让网站更快速的响应用户请求, 这些事情都发生在开发之...