在使用mq异步框架的过程中,如何更好保证事务提交成功后,mq生产者才生产对应的消息

JYYH 发布于 2020/08/24 16:39
阅读 1K+
收藏 2

开源之夏第三届火热来袭,高校学生参与赢万元奖金!>>>

因为我们公司目前有一些场景上用到mq的地方,目前的做法是先插入数据库,在数据库的后面追加异步方法,做MQ生产。伪代码如下

    @Transactional(rollbackFor = Exception.class)
    public int insert(){
        // 插入数据库
        int insert = dao.insert(object);
        // 异步方法
        asynchMq(object);
        return insert;
    }

 

加载中
0
迷城技术
迷城技术

你可以把插入数据库的地方封装成一个独立的service事务,然后事务完成以后,再发送MQ不就行了

J
JYYH
监控不了吧,分布式事务
0
f
freezingsky

你应该是在本地事务提交完成后,再操作MQ。你的代码有误,请调整。

另外 ,运行过程 ,有可能 本地提交成功后,插入MQ时失败(死机重启或者其他各种不可控原因),还需要添加补偿机制。

f
freezingsky
回复 @JYYH : 年轻人,我能这么说,就意味着,它可以被这么做。不存在 你的说的“做不到”:sunglasses:
J
JYYH
我这边事务是通过spring @Transactional来管理的,加上微服务应用,做不到本地事务提交完成再操作MQ的。 确实会有一定几率导致插入mq失败,所以觉得当前的处理逻辑不是很健壮
0
Asdybing
Asdybing

有种队列叫 延时队列, 不过这也涉及消息实时性的问题。

0
练打字的
练打字的
用信号,或者换成同步,信号的话可能会被阻塞一会
0
JavaGG
JavaGG

看你这个mq的即时性要求吧,,你可以生成一个唯一ID事务成功,异步mq检查到这id成功了再发请求,这基本上就100%无问题了

0
魔力猫
魔力猫

两个办法。

一个是MQ业务里面有代码能验证提交的这个消息是否是正确的。比如会判断数据库里面是否有记录。

另一个是切面执行MQ,把MQ和插入独立成两个。

魔力猫
魔力猫
回复 @JYYH : 差不多。如果要么消费者自己有判断能力。要么@AfterReturning切面发送消息。
J
JYYH
第一种方法:我是不是可以理解为,使用数据表id来判断呢,然后在mq服务这边判断是否有记录呢,如是微服务应该,是否还可行呢 第二种:那mq在AOP,@AfterReturning成功后发送mq?
0
Kit_lee
Kit_lee

既然是要保证事务提交后再发MQ,为什么要将异常发MQ的语句写在insert的事务方法内?

0
八零后大叔
八零后大叔

AOP,@AfterReturning

0
wang_dongjiang
wang_dongjiang

MQ自带事务啊

0
无花_java
无花_java

三种方式

1> 将mq生成放到表里, 和上面mysql在一个库, 定时任务调度定时发送

2> 监听事务的提交, 事务提交以后在发送mq

3> 通过事务消息去保证 eg rockertmq消息

OSCHINA
登录后可查看更多优质内容
返回顶部
顶部
返回顶部
顶部