分布式事务综合案例分析【实用篇】

分布式事务综合案例分析【实用篇】
强烈推介IDEA2020.2破解激活,IntelliJ IDEA 注册码,2020.2 IDEA 激活码

我们已经了解了四种分布式事务解决方案,2PC【链接】、TCC【链接】、可靠消息最终一致性【链接】、最大努力通知【链接】,每种解决方案我们通过案例开发进行学习,本章节我们结合互联网金融项目中的业务场景,来进行分布式事务解决方案可行性分析。

一、系统介绍


P2P金融又叫 P2P信贷。其中 P2P是 peer-to-peer 或 person-to-person 的简写,意思是:个人对个人。P2P金融指 个人与个人间的小额借贷交易,一般需要借助电子商务专业网络平台帮助借贷双方确立借贷关系并完成相关交易手续。借款者可自行发布借款信息,包括金额、利息、还款方式和时间,实现自助式借款。投资者根据借款人发布的信息,自行决定出借金额,实现自助式借贷。 目前,国家对 P2P行业的监控与规范性控制越来越严格,出台了很多政策来对其专项整治。并主张采用“银行存管模式”来规避 P2P平台挪用借投人资金的风险,通过银行开发的“银行存管系统”管理投资者的资金,每位 P2P平台用户在银行的存管系统内都会有一个独立账号,平台来管理交易,做到资金和交易分开,让 P2P平台不能接触到资金, 就可以一定程度避免资金被挪用的风险。

什么是银行存管模式银行存管模式涉及到2套账户体系,P2P平台和银行各一套账户体系。投资人在 P2P平台注册后,会同时跳转到银行再开一个电子账户,2个账户间有一一对应的关系。当投资人投资时,资金进入的是平台在银行为投资人开设的二级账户中,每一笔交易,是由银行在投资人与借款人间的交易划转,P2P平台仅能看到信息的流动。

模块说明:
【1】统一账号服务:用户的登录账号、密码、角色、权限、资源等系统级信息的管理,不包含用户业务信息。
【2】用户中心:提供用户业务信息的管理,如会员信息、实名认证信息、绑定银行卡信息等,“用户中心”的每个用户与“统一账号服务”中的账号关联。
【3】交易中心:提供发标、投标等业务。
【4】还款服务:提供还款计划的生成、执行、记录与归档。
【5】银行存管系统(模拟):模拟银行存管系统,进行资金的存管,划转。

二、注册账号案例分析


业务流程:采用用户、账号分离设计(这样设计的好处是,当用户的业务信息发生变化时,不会影响的认证、授权等系统机制),因此需要保证用户信息与账号信息的一致性。

根据上述需求进行解决方案分析
1】采用可靠消息一致性方案:可靠消息一致性要求只要消息发出,事务参与者接到消息就要将事务执行成功,不存在回滚的要求,所以不适用。
【2】最大努力通知方案:最大努力通知表示发起通知方执行完本地事务后将结果通知给事务参与者,即使事务参与者执行业务处理失败发起通知方也不会回滚事务,所以不适用。
【3】采用 Seata实现 2PC:在用户中心发起全局事务,统一账户服务为事务参与者,用户中心和统一账户服务只要有一方出现问题则全局事务回滚,符合要求。实现方法如下:
   1、用户中心添加用户信息,开启全局事务;
   2、统一账号服务添加账号信息,作为事务参与者;
   3、其中一方执行失败 Seata对 Sql进行逆操作删除用户信息和账号信息,实现回滚;
【4】采用 Hmily实现:TCC也可以实现用户中心和统一账户服务只要有一方出现问题则全局事务回滚,符合要求。 实现方法如下:
   1、用户中心try:添加用户,状态为不可用,confirm:更新用户状态为可用,cancel:删除用户;
   2、统一账号服务 try:添加账号,状态为不可用,confirm:更新账号状态为可用,cancel:删除账号;

三、存管开户


业务流程:根据政策要求,P2P业务必须让银行存管资金,用户的资金在银行存管系统的账户中,而不在 P2P平台中,因此用户要在银行存管系统开户。
 

解决方案分析:P2P平台的用户中心与银行存管系统之间属于跨系统交互,银行存管系统属于外部系统,用户中心无法干预银行存管系统,所以用户中心只能在收到银行存管系统的业务处理结果通知后积极处理,开户后的使用情况完全由用户中心来控制。

根据上述需求进行解决方案分析:
【1】采用 Seata实现 2PC:需要侵入银行存管系统的数据库,由于它的外部系统,所以不适用;
【2】采用 Hmily实现 TCC:TCC侵入性更强,所以不适用;
【3】基于 MQ的可靠消息一致性如果让银行存管系统监听 MQ则不合适,因为它的外部系统。如果银行存管系统将消息发给 MQ用户中心监听 MQ是可以的,但是由于相对银行存管系统来说用户中心属于外部系统,银行存管系统是不会让外部系统直接监听自己的 MQ的,基于 MQ的通信协议也不方便外部系统间的交互,所以本方案不合适;
【4】最大努力通知方案:银行存管系统内部使用MQ,银行存管系统处理完业务后将处理结果发给MQ,由银行存管的通知程序专门发送通知,并且采用互联网协议通知给第三方系统(用户中心);
下图中发起通知即银行存管系统
 

四、满标审核


业务流程:在借款人标的募集够所有的资金后,P2P运营管理员审批该标的,触发放款,并开启还款流程。
 

根据上述需求进行解决方案分析:
【1】采用 Seata实现 2PCSeata在事务执行过程会进行数据库资源锁定,由于事务执行时长较长会将资源锁定较长时间,所以不适用。
【2】采用 Hmily实现 TCC:本需求对业务一致性要求较低,因为生成还款计划的时长较长,所以不要求交易中心修改标的状态为“还款中”就立即生成还款计划,所以本方案不适用。
【3】基于MQ的可靠消息一致性:满标审批通过后由交易中心修改标的状态为“还款中”并且向还款服务发送消息,还款服务接收到消息开始生成还款计划,基本于 MQ的可靠消息一致性方案适用此场景。
【4】最大努力通知方案:满标审批通过后由交易中心向还款服务发送通知要求生成还款计划,还款服务并且对外提供还款计划生成结果校对接口供其它服务查询,最大努力通知方案也适用本场景。

五、总结


事务的基本概念以及本地事务特性。CAP、BASE理论的概念。2PCTCC可靠消息最终一致性最大努力通知各类型原理及特性。不同分布式事务类型的应用场景讨论。

  2PC TCC 可靠消息最终一致性 最大努力通知
一致性 强一致性 强一致性 最终一致 最终一致
吞吐量
实现复杂度

2PC】最大的诟病是一个阻塞协议。RM在执行分支事务后需要等待 TM的决定,此时服务会阻塞并锁定资源。由于其阻塞机制和最差时间复杂度高,因此,这种设计不能适应随着事务涉及的服务数量增加而扩展的需要,很难用于并发较高以及子事务生命周期较长(long-runningtransactions)的分布式服务中。如果拿 TCC事务的处理流程与 2PC两阶段提交做比较,2PC通常都是在跨库的 DB层面,而 TCC则在应用层面的处理,需要通过业务逻辑来实现。这种分布式事务的实现方式的优势在于,可以让应用自己定义数据操作的粒度,使得降低锁冲突、提高吞吐量成为可能。而不足之处则在于对应用的侵入性非常强,业务逻辑的每个分支都需要实现try、confirm、cancel三个操作。此外,其实现难度也比较大,需要按照网络状态、系统故障等不同的失败原因实现不同的回滚策略。典型的使用场景:登录送优惠券等。
可靠消息最终一致性事务】适合执行周期长且实时性要求不高的场景。引入消息机制后,同步的事务操作变为基于消息执行的异步操作,避免了分布式事务中的同步阻塞操作的影响,并实现了两个服务的解耦。典型的使用场景:注册送积分,登录送优惠券等。
最大努力通知】是分布式事务中要求最低的一种,适用于一些最终一致性时间敏感度低的业务;允许发起通知方处理业务失败,在接收通知方收到通知后积极进行失败处理,无论发起通知方如何处理结果都会不影响到接收通知方的后续处理;发起通知方需提供查询执行情况接口,用于接收通知方校对结果。典型的使用场景:银行通知、支付结果通知等。
总结在条件允许的情况下,我们尽可能选择本地事务单数据源,因为它减少了网络交互带来的性能损耗,且避免了数据弱一致性带来的种种问题。若某系统频繁且不合理的使用分布式事务,应首先从整体设计角度观察服务的拆分是否合理,是否高内聚低耦合?是否粒度太小?分布式事务一直是业界难题,因为网络的不确定性,而且我们习惯于拿分布式事务与单机事务 ACID做对比。无论是数据库层的XA、还是应用层TCC、可靠消息、最大努力通知等方案,都没有完美解决分布式事务问题,它们不过是各自在性能、一致性、可用性等方面做取舍,寻求某些场景偏好下的权衡。

本文来源程序猿进阶,由javajgs_com转载发布,观点不代表Java架构师必看的立场,转载请标明来源出处:https://javajgs.com/archives/8217

发表评论