请稍等 ...
×

采纳答案成功!

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

流程问题

不会走trycatch的方法,我在控制台查看消息,也没有发送消息列表成功
图片描述![图片描述](http://img1.sycdn.imooc.com//szimg/5e7f8bf709000bde19371017.jpg
他过一段时间后就自己查询下面那个方法,因为上面没有创建日志,所以返回的是一个null
图片描述
不懂的就是,他走了rollback方法,但是数据库的数据没有回滚,还是pass的

正在回答

2回答

您好,您代码的:

com.sqlpay.contentcenter.rocketmq.AddBonusTransactionListener#executeLocalTransaction

MessageHeaders headers = message.getHeaders();
String transactionId = (String) headers.get(RocketMQHeaders.TRANSACTION_ID);
Integer shareId = (Integer) headers.get("share_id");

里面:

Integer shareId = (Integer) headers.get("share_id");

这一行应该是有问题的。RocketMQ比较奇葩,不管你设置的是啥,它都会强制转换成字符串。所以是没办法直接用Integer接收的。在这一行直接就会抛异常了。。。。。

所以得改成:

Integer shareId = Integer.valueOf((String) headers.get("share_id"));

这是第一个问题。



第二,你的Service代码:

public Share auditById(Integer id, ShareAuditDTO auditDTO) {
    //1.查询share时候存在,或者当前审核状态不为待审核,抛出异常
    Share existsShare = shareMapper.selectByPrimaryKey(id);
    if (existsShare == null) {
        throw new IllegalArgumentException("参数非法!该分享不存在");
    }
    if (!Objects.equals(AuditStatusEnum.NOT_YET.name(), existsShare.getAuditStatus())) {
        throw new IllegalArgumentException("参数非法!该分享已审核通过或不通过");
    }
    //2.审核资源,设置状态
    auditByIdInDb(id, auditDTO);
    //3.如果通过,发送消息给rocketMq,让用户中心去消费为发布人添加积分
    if (AuditStatusEnum.PASS.equals(auditDTO.getAuditStatusEnum())) {
        // 发送半消息
        String transactionId = UUID.randomUUID().toString();
        rocketMQTemplate.sendMessageInTransaction(
                "tx-add-bonus-group",
                "add-bonus",
                MessageBuilder
                        .withPayload(
                                UserAddBonusMsgDTO.builder()
                                        .userId(existsShare.getUserId())
                                        .bounds(50)
                                        .build()
                        )
                        .setHeader(RocketMQHeaders.TRANSACTION_ID, transactionId)
                        .setHeader("share_id", id)
                        .build(),
                auditDTO
        );
    } else {
        this.auditByIdInDb(id, auditDTO);
    }
    return existsShare;
}


你都先auditByIdInDb完了,才发消息,那么,只要:

  1. auditByIdInDb不出异常

  2. rocketMQTemplate.sendMessageInTransaction不报异常,数据库里数据的状态就已经变掉了。

你在RocketMQ那个Listener里记录的日志什么的,都没用了。这个流程是有问题的。


可以:

  1. 再次复习下rocketmq章节事务的流程

  2. 参考下我的代码:https://git.imooc.com/coding-358/content-center/src/master/src/main/java/com/itmuch/contentcenter/service/content/ShareService.java 以及 https://git.imooc.com/coding-358/content-center/src/master/src/main/java/com/itmuch/contentcenter/rocketmq/AddBonusTransactionListener.java


1 回复 有任何疑惑可以回复我~
  • 恩 第二个问题 我昨天也看到了 哈哈 没细心 感谢目哥
    回复 有任何疑惑可以回复我~ 2020-03-30 14:15:05
提问者 终极无敌霸王龙战神 2020-03-29 01:54:55

content-center:https://gitee.com/comgreen/content-center.git

0 回复 有任何疑惑可以回复我~
问题已解决,确定采纳
还有疑问,暂不采纳
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号