• roketmq 并行发送两条消息,一条消息更新的前半部分,一条消息更新的后半部分,且操作的数据是同一张表时,会导致数据不准确的问题


    场景:service层更新了取消考勤的数据,更新以后需要发消息更新课次的实际出勤人数和应出勤人数,

    实际出勤人数是一个消息,应出勤人数是一个消息。

    问题:在取消考勤以后,数据没有更新正确,然后手动触发更新的接口发现数据更新正确

    猜想:猜想是取消考勤操作的数据太多,导致事务还没有真正的提交。消费者消费消息太快,导致在更新课次实际出勤人数的时候,事务还没有提交,导致的数据更新不准确。

    验证:

    TransactionSynchronizationManager
    .registerSynchronization(new TransactionSynchronizationAdapter() {
    @Override
    public void afterCommit() {
            // 事务提交后,发送更新课次实际出勤mq逻辑
            // 更新班级下的课次应出勤人数
            }
    });
    然后又使用半消息体系(取消考勤的同时提交一条系统记录插入,待半消息能从系统中查出来时,取消考勤的事务一定是提交了的)
    结果,还是数据不准确,感觉是不是代码本身的问题哦。慢慢写日志,记录两条消息更新的数据,猛然发现,
    1、更新课次实际出勤人数时,是将课次统计记录先查出来,计算实际出勤人数,在更新实际出勤人数部分。
    2、更新课次应出勤人数时,将课次统计记录先查出来,计算应出勤人数,在更新应出勤人数部分。
    问题来了,他们两条消息查出来的数据都是任意一条消息更新之前的数据,导致更新只更新了某一条消息更新数据的部分(比如更新了实际出勤部分,或更新了应出勤部分)
    故此导致了有时候数据更新准确,数据更新不准确

    解决办法,放到同一消息中,先更新实际出勤人数(事务已经提交),在更新应出勤人数(查询的数据是已经更新后的)。问题解决
  • 相关阅读:
    一致性哈希的理解与实践
    nil in Go
    为什么Go没有math.Min/Max(int, int) 函数?
    What happens when I type kubectl run?
    kubelet简要分析
    编译安装nginx和模块
    nginx与tengine添加check模块(nginx_upstream_check_module)
    多台ESXI 6.5 添加 iSCSI 共享存储 --centos 7.4 作为target
    Cannot open the disk '/vmfs/volumes/5e97f429-a56d6ea0-1ef3-000c29a09445/oracle_node1/oracle_node1_1.vmdk' or one of the snapshot disks it depends on.
    RabbitMQ windows2016 镜像模式 haproxy+keepalived
  • 原文地址:https://www.cnblogs.com/fancy2041/p/12651529.html
Copyright © 2020-2023  润新知