关于MQ异步调用,调用失败的处理方式
@Transactional
void a(){
b();//插入数据a,id=101
c(101);
}
/*
* 异步执行
*/
@Async
void c(int id){
// 查询
Obj data = query(id);
// 调用mq
push(data)
}
在一个事务里面,插入数据,然后在另一个线程里查询并推送数据。
这里query的时候,可能由于事务没有提交,查询不到数据的。
问题
mq异步调用失败,如何保证数据一致性?
已知方案:调用失败写入数据库,然后定时扫表,做补偿,不过感觉这种效率不高。
还有其他更好的方案吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
按你的使用场景,推送数据必须得在数据创建事务成功之后执行,这里必须有个先后。你可以将推送这个操作异步执行,消息队列有一搬有ack机制,确保消息没丢失。这时候监听消息队列的程序会执行推送,如果推送成功做标记。如果推送失败也标记记录时间,也可以推到另一个消息队列约定多少分钟重试。实在不行就彻底标记失败,或者回滚之前创建的数据。这个才是最终一致性。
如果是并行的操作,就得使用消息队列的confirm机制了。
既然c()是插入动作,那么你不妨把这个动作在程序里留一份返回的id当然可以留下来,这时候程序里的就相当于是你查出来的。这样的话query(id)可以完全不用去查询库