关于银行转账引发的分布式事务思考
转载自:https://www.cnblogs.com/sujing/p/11006424.html
数据库的四大特征:原子性、一致性、隔离性、持久性。
分布式理论
CAP理论,一个分布式系统不可能同时满足一致性、可用性、分区容错性三个基本需求,最多同时只能满足其中两项。
一致性:在分布式系统中,数据在多个副本之间能否保持一致的特性,也就是说对某个数据进行写操作后立马执行读操作,必须能读取到刚刚写入的值。
可用性:任意被无故障节点接收到的请求,必须能够在有限的时内响应结果。
分区容错性:如果集群中的机器被分成了两部分,这两部分不能互相通信,系统是否能继续正常工作。
分布式事务
分布式事务的解决方案有很多,如XA协议、TCC三阶段提交、基于消息队列等等,以下以基于消息队列为例,流程如下:
1、A银行对账户进行检查校验、进行全额扣减,并存到转账流水表;
2、将对B银行的请求异步写入队列,主线程返回;
3、启动后台程序从队列获取待处理数据;
4、后台程序对B银行接口进行远程调用;
5、定期的从转账流水表中读取状态为“待处理”且最后更新的时间距当前时间大于某个阈值的数据,调用B银行处理结果查询接口,若未查到结果则重新放入消息队列进行补偿,若查到则更新该数据状态;
6、B银行对转入账户进行检查校验,根据唯一转账流水Id在转账日志表中查找判断该转账是否已经处理过,若未处理则进行金额增加,并存到转账日志表,否则直接返回日志表处理结果;
7、B银行处理完成后回调A银行接口通知处理结果;
转账流水表设计如下:
字段名称 | 字段描述 |
id | 交易流水id |
accountNo | 银行账户 |
targetBankNo | 目标银行编码 |
targetAccountNo | 目标银行卡号 |
targetAccountName | 目标银行卡持卡人姓名 |
amount | 交易金额 |
status | 交易处理状态(待处理、处理成功、处理失败) |
createTime | 创建时间 |
lastUpdateTime | 最后更新时间 |
转账日志表:
字段名称 | 字段描述 |
id | 编号 |
transId | 交易流水号,对应转账流水表id |
sourceAccountNo | 源银行账户,对应转账流水表accountNo |
targetAccountNo | 目标银行卡号,对应转账流水表targetAccountNo |
targetAccountName | 目标银行卡持卡人姓名,对应转账流水表targetAccountName |
amount | 交易金额 |
status | 交易处理状态(处理成功、处理失败) |
createTime | 创建时间 |
以上A银行通过本地事务保证日志记录+后台线程轮询保证消息不丢失。B银行通过本地事务保证日志记录从而保证消息不重复消费!B银行在回调A银行的接口时会通知处理结果,如果转账失败,A银行会根据处理结果进行回滚。