@Transactional
void a(){
b();//插入数据a,id=101
c(101);
}
/*
* 异步执行
*/
@Async
void c(int id){
// 查询
Obj data = query(id);
// 调用mq
push(data)
}
在一个事务里面,插入数据,然后在另一个线程里查询并推送数据。
这里query的时候,可能由于事务没有提交,查询不到数据的。
问题
mq异步调用失败,如何保证数据一致性?
已知方案:调用失败写入数据库,然后定时扫表,做补偿,不过感觉这种效率不高。
还有其他更好的方案吗?
按你的使用场景,推送数据必须得在数据创建事务成功之后执行,这里必须有个先后。你可以将推送这个操作异步执行,消息队列有一搬有ack机制,确保消息没丢失。这时候监听消息队列的程序会执行推送,如果推送成功做标记。如果推送失败也标记记录时间,也可以推到另一个消息队列约定多少分钟重试。实在不行就彻底标记失败,或者回滚之前创建的数据。这个才是最终一致性。
如果是并行的操作,就得使用消息队列的confirm机制了。