可靠事件实现微服务下最终一致性事务

通过《消费者实现应用内分布式事务》、《生产者实现应用内分布式事务管理》、《实现持久订阅消费者》三个章节的实践,其实我们已经可以通过消息队列实现多应用的分布式事务,应用内的事务保证了消息不会被重复生产消费、持久化订阅保证了消息一定会被消费(进入死信队列特殊处理),但其对于业务来说耦合性还是太强,在进行业务处理的同时消息处理名,其采用的仍然是应用内的事务处理,并不适合在大型高性能高并发系统实践,那么本章将通过本地事务+消息队列+外部事件定义表+定时任务实现解耦。
(目前主要实现微服务下最终一致性事务的方案主要是:可靠事件;补偿模式;TCC(Try-Confirm-Cancel);三种,本案例为可靠事件方式)

场景描述:
本场景就拿最常用的转账业务阐述:
在工行ICBC有账号Card001,其中存于500元;
在中行BOC有账号Card002,其中也存有500元;
此时从Card001账号转账至Card002账号300元。

系统设计:
工行系统ICBCPro,该工程主要实现两个功能(实现转出金额生成转账事件;定时任务发出转账事件至消息队列),主要参考《生产者实现应用内分布式事务管理》实现;
中行系统BOCPro,该工程主要实现两个功能(从消息队列下载转账事件;定时任务对转账事件处理并更新转入账号金额),主要参考《消费者实现应用内分布式事务》实现;
此场景仅需要通过P2P消息模式即可。

构建ICBCPro工程

A、实现转出金额生成转账事件
1、构建数据库相关表以及基础数据:
转出账号数据

转出事件记录

消息队列

消息控制台

2、执行单元测试代码实现转账,此时账户扣除与转账事件记录均在本地事务内:

//ICBC中账户card001转出300元

@Test
	public void tranfer(){
		EventLog eventLog = new EventLog();
		eventLog.setAmount(new BigDecimal(300));
		eventLog.setFromcard("card001");
		eventLog.setTocard("card002");
		eventLog.setEventstate(EventState.NEW);
		eventLog.setTransferDate(new Date());
		eventLogService.transfer(eventLog,new BigDecimal(300));	
	}

账户信息:

事件记录


B、定时任务发出转账事件至消息队列

对于事件记录表,我们可以定义一个定时任务,将所有的NEW状态事件全部发出,此时需要保证消息的可靠性,采用XA事务实现,但已经不影响我们业务的响应了,实现解耦、快速响应,下面贴出核心实现代码:
1、首选实现数据排它锁场景下的查询与更新:
/**
	 * 在排它锁场景下数据更新,保证数据的可靠性
	 */
	@Override
	public void updateEventstateById(String id, EventState eventState) {
		EventLog eventLog=findEventLog4Update(id);
		eventLog.setEventstate(eventState);
		emJ1.merge(eventLog);
	}

	/**
	 * 实现排它锁查询
	 */
	@Override
	public
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值