路过的讨论一下:纠结MQ是在放service事务外还是事务内? 400 报错
如一方法
@Transactional
XXService
public void xxx(){
a();
b();
mq();
}
如果mq放在事务内,a()和b()事务提交时间可能比较长,mq()发出去后,消费者可能在消费消息时,a,b方法还没提交完毕(等事务吧),这时数据就会乱了。
改成下面的
YYYController
public void hello(){
xxxService.xxx();// 里有a,b方法
mq();
}
如果xxx()方法执行成功了,mq()失败了,那么mq消息发不了,消息丢失。
有什么好的办法不?各位大佬
一般是放在事务之外. 主要原因是, 很多时候DB事务提交 有可能会撞中各种问题而回滚. 至于MQ,一般来说,都做了高可用和本地的异步提交.
######你mq()成功了,也只代表消息发出去了,消息的消费者有没有正常收到,有没有正常处理还是个未知数,所以我感觉mq()反正都是没办法与前面的两个方法做到强一致的,不如放事务外面。不过具体还得结合业务来看。
######1. 可以使用spring提供的链式事务管理器 (ChainedTransactionManager) 把多个资源操作在一个事务中提交(假如 事务在提交过程中 db 或mq 服务挂掉时,这种方式会出问题 。涉及到多个资源属于分布式数据一致性问题)
2.考虑使用Rocketmq 的事务消息 (有消息回查机制)
######消息补偿+幂等
######一般的业务建议放在service层事务外,mq内部一般会有处理投递失败的处理机制,实在不行可以捕捉mq的异常,失败了可以做重试、日志记录等补偿操作,达到最终一致性就可以了
######也可以将a(),b()设置成独立事务,先提交,然后mq()。
######多谢各位的说法
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。