请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

如何实现提交数据库事务之后,再发送mq

项目中遇到一个问题,上游业务修改订单状态之后,发送一个订单状态变更的广播出来,各个下游业务监听该topic完成后续业务,如果mq发生太快,数据还没入库,下游获取的是旧的状态。
怎样才能保证写表之后,发送mq呢

正在回答

1回答

大漠风 2018-09-23 01:50:59

正常的情况下,我们可以使用默认的方式进行DB和MQ的两个数据源的事务管理,这样的话,在DB的事务提交的时候,再触发MQ的事务的提交。这样,MQ上的消息触发其他的业务过程中,读数据库肯定读到的是已经提交的状态。

但是,如果使用Spring Data或Hibernate之类的框架,在你提交事务是时候,这个框架不会立刻把数据状态提交到DB上,而是保存在它的context中。之前我们就遇到过,使用Spring Data时,你说的那种问题。即使在方法结束前使用repository的flush()方法,也没有立刻提交到DB。

Spring Data的这种机制是为了在单服务的情况下,更有效的利用缓存。但是在分布式环境下,就会造成问题。

这种情况下,你试一下用代码方式进行管理事务,而不是用@Transactional的标签。然后也尝试一下repository的flush()方法。

0 回复 有任何疑惑可以回复我~
  • 提问者 木星鸽_手机 #1
    多谢老师节日抽空回答~
    其实我的问题更浅,我们用的是mybatis
    主要是不明白transactional标签的执行时机,比如在transaction标签注解的方法中,代码如下
    
    //先完成数据库写入
    int i=dao.save(order)
    //发送mq
    if i>0
        mqService.send(msg)
    
    这样写是不是能保证入库成功了,才发送消息
    如果能,transactionnal标签背后是怎么执行的?看起来mq也被包裹在这个方法里了
    回复 有任何疑惑可以回复我~ 2018-09-23 14:30:07
  • 这是两个数据源的操作,事务是依次提交,至于谁先谁后,你可以打印日志看看,一般是数据库在前,因为是在数据库事务管理器上同步mq的事务。
    回复 有任何疑惑可以回复我~ 2018-09-23 15:33:32
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信