最大努力通知
最大努力通知型( Best-effort delivery)是最简单的一种柔性事务,适用于一些最终一致性时间敏感度低的业务,且被动方处理结果 不影响主动方的处理结果。典型的使用场景:如银行通知、商户通知等。最大努力通知型的实现方案,一般符合以下特点:
- 不可靠消息:业务活动主动方,在完成业务处理之后,向业务活动的被动方发送消息,直到通知N次后不再通知,允许消息丢失(不可靠消息)。
- 定期校对:业务活动的被动方,根据定时策略,向业务活动主动方查询(主动方提供查询接口),恢复丢失的业务消息。
ps 结合自身项目经历,我原公司的计费系统也是采用最大努力通知的方式,将结果通过多次回调到业务方的回调接口上,同时提供查询接口供业务方查询。多次回调是靠rocketMq的消息重试机制实现。
TCC两阶段补偿型
TCC方案是可能是目前最火的一种柔性事务方案了。关于TCC(Try-Confirm-Cancel)的概念,最早是由Pat Helland于2007年发表的一篇名为《Life beyond Distributed Transactions:an Apostate’s Opinion》的论文提出。
TCC的作用主要是解决跨服务调用场景下的分布式事务问题
tcc基本概念
TCC是Try-Confirm-Cancel的简称:
try阶段:
完成所有业务检查(一致性),预留业务资源(准隔离性)
Confirm阶段:
确认执行业务操作,不做任何业务检查, 只使用Try阶段预留的业务资源。
Cancel阶段:
取消Try阶段预留的业务资源。
tcc要求我们原来的一个接口,现在做成三个接口来分别实现try 、confirm、cancel功能,来保证事务的最终一致性。
tcc与2pc的区别
TCC两阶段提交与XA两阶段提交的区别是:
XA是资源层面的分布式事务,强一致性,在两阶段提交的整个过程中,一直会持有资源的锁。
只是一次方法调用,其内部会委派给TransactionManager进行真正的两阶段提交,因此开发者从代码层面是感知不到这个过程的。
而事务管理器在两阶段提交过程中,从prepare到commit/rollback过程中,资源实际上一直都是被加锁的。
如果有其他人需要更新这两条记录,那么就必须等待锁释放。
TCC是业务层面的分布式事务,最终一致性,不会一直持有资源的锁。
1. try过程的本地事务,是保证资源预留的业务逻辑的正确性。
2. confirm/cancel执行的本地事务逻辑确认/取消预留资源,以保证最终一致性,也就是所谓的补偿型事务(Compensation-Based Transactions)。
3. 由于是多个独立的本地事务,因此不会对资源一直加锁。
可靠消息最终一致性
息发送一致性:是指产生消息的业务动作与消息发送的一致。也就是说,如果业务操作成功,那么由这个业务操作所产生的消息一定要成功投递出去(一般是发送到kafka、rocketmq、rabbitmq等消息中间件中),否则就丢消息。
具体实现方式不同消息中间件,实现方式不同
kafka事务消息
基于两阶段提交,具体原理参靠kafka02_producer。
RocketMq事务消息
两阶段提交+消息回查机制
参考rocketmq05_TransactionalMessage
本地消息表(不支持事务消息的mq)
数据保存的时候同时往本地消息表插入一条数据,另起一个线程定时轮询消息表,发送数据。