纯技术干货分享:分布式事务处理方式总结
事务补偿这种方式保证的是事务的最终一致性,即如果发生意外,会存在一个时间窗口(例如2S),在这个窗口内DB和缓存间是不一致的,但能保证最终两者的数据是一致的。至于定时任务周期的设定,要结合业务对“脏”数据的敏感程度以及系统的负载。 事务型消息 对于一个金融系统,假设有一个需求是用户注册成功后自动为用户创建一个账户。客户的信息维护在客户中心系统,客户的账户信息维护的账务中心系统,如果用户注册成功,必须保证客户的账户在账务系统创建成功。这显然也是一个分布式事务问题。 处理这个问题,显然也可以采用上一小节介绍的事务补偿机制来处理。但注册和开户并不要求一定是同步完成,且需要感知用户注册成功事件的系统并不只有账务系统一个(例如营销系统可能也需要感知用户注册成功的事件,给用户发优惠券),所以使用消息机制异步通知更加合适。那么问题就变成了“如果用户注册成功,一定要保证消息发送成功”。 应对这种场景,可以使用事务型消息。但前提条件是使用的MQ中间件必须支持事务型消息,比如阿里的RocketMQ。目前市面上其它一些主流的MQ中间件都不支持事务型消息,比如Kafka和RabbitMQ都不支持。 下面的序列图是事务型消息的执行流程: ![]()
细心的小伙伴会发现,如果在上图中的第5步发生问题导致发送commit失败,不还是会导致消息发布者和消息订阅者间事务的不一致吗?为了防止这种情况的发生,增加MQ超时回调机制。 下面的序列图是事务型消息commit失败时的执行流程: ![]() 当MQ长时间收不到发布者的commit/rollback通知时,MQ会回调发布者应用询问本地事务是否执行成功,是commit还是rollback之前的消息。发布者需要提供对应的callback,在callback中判断本地事务是否执行成功。 TCC两阶段提交 在某些场景下,一个分布式事务可能会涉及到多个参与者,且每个参与者需要根据自己当时的状态对事务进行响应。 假设这样一个场景,一个电商网站可以允许用户在支付时选择多种支付方式。例如总共需要支付100元钱,用户可以选择积分支付10元,账户余额支付90元。用户的积分由营销系统负责,账户余额由账务系统负责,订单的状态管理由订单系统负责。
应对这种分布式事务场景,可以采用TCC两阶段提交的方式进行处理。 (编辑:西安站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |