事务@Transactional + RabbitMQ 的事务

问题:由于处理业务逻辑中开启了事务,并且在事务中修改数据,随后使用消息队列MQ异步添加到ES中,由于处理文档流程未提交事务(MQ消费过快),在添加到ES过程查询的数据不是最新的,导致同步到ES的数据不完整

旧代码:

    /**
     * 批量添加文件关联
     * @param fileModuleVo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ResultMsg fileRelevanceModule(List<FileModuleVo> fileModuleVo) {
        for (FileModuleVo moduleVo : fileModuleVo) {
            // 1、修改已上传的文件
            sysUserFileLogService.updateById(new SysUserFileLog(moduleVo.getFileLogId(), moduleVo.getSourceType(), moduleVo.getIsCooperate() + 1, moduleVo.getMatterName(), moduleVo.getFileGroup(), moduleVo.getClassId()));

            // 2、添加文件关联
            if (!moduleVo.getModalList().isEmpty()){
                List<SysFileRelevanceModule> modules = new ArrayList<>();
                for (ModalListVo modalListVo : moduleVo.getModalList()) {
                    SysFileRelevanceModule module = new SysFileRelevanceModule();
                    BeanUtils.copyProperties(moduleVo, module);
                    BeanUtils.copyProperties(modalListVo, module);
                    module.setRelevanceId(StringUtils.isNotBlank(moduleVo.getRelevanceId()) ? moduleVo.getRelevanceId():modalListVo.getAgendaMatterRelatableId());
                    module.setRelevanceName(StringUtils.isNotBlank(moduleVo.getRelevanceId()) ? moduleVo.getRelevanceName():modalListVo.getAgendaMatterRelatableName());
                    modules.add(module);
                }
                super.saveBatch(modules);
            }else{
                SysFileRelevanceModule module = new SysFileRelevanceModule();
                BeanUtils.copyProperties(moduleVo, module);
                super.save(module);
            }

        }
        // 同步搜索引擎
        rabbitMQSend.fileLogUpload(fileModuleVo);
        return ResultMsg.success(fileModuleVo);
    }



    /**
     * 投递文档上传日志
     */
    public void fileLogUpload(List<FileModuleVo> fileModuleVo) {
        try {
            task.rabbitTemplate.convertAndSend(RabbitMqConst.FILE_LOG_DIRECT_EXCHANGE, RabbitMqConst.FILE_LOG_ROUTING_KEY, fileModuleVo);
        } catch (Exception e) {
            log.error("文档同步搜索引擎投递失败:{}", JSON.toJSONString(fileModuleVo));
        }
    }



    /**
     * 同步到ES
     */
    @RabbitListener(queues = RabbitMqConst.FILE_LOG_QUEUE)
    public void fileLogSyncEs(List<FileModuleVo> fileModuleVo) {
        // 1、组装数据
        List<EsDocumentVo> params = new CopyOnWriteArrayList<>();
        for (FileModuleVo moduleVo : fileModuleVo) {
            // TODO 由于处理【批量添加文件关联】事务未提交,查询的数据不是更新后的
            SysUserFileLog fileLogInfo = fileLogService.getById(moduleVo.getFileLogId());
            // 文档添加上级
            sysUserService.userLeaders(fileLogInfo.getEnterpriseId(), fileLogInfo.getUserId(), moduleVo.getFileLogId(), moduleVo.getUserIds());
            if (moduleVo.getSourceType() != 1) continue;
            EsDocumentVo documentVo = new EsDocumentVo();
            documentVo.setId(moduleVo.getFileLogId());
            documentVo.setUserId(fileLogInfo.getUserId());
            documentVo.setUserName(fileLogInfo.getUserName());
            documentVo.setUserAvatar(fileLogInfo.getUserAvatar());
            documentVo.setUsers(sysUserFileRelevanceService.getUsers(moduleVo.getFileLogId()));
            documentVo.setEnterpriseId(fileLogInfo.getEnterpriseId());
            documentVo.setEnterpriseName(fileLogInfo.getEnterpriseName());
            documentVo.setFoldUrl(fileLogInfo.getFolderUrl());
            documentVo.setOldFileName(fileLogInfo.getOldFileName());
            documentVo.setFileName(fileLogInfo.getFileName());
            documentVo.setCompileFileName(fileLogInfo.getCompileFileName());
            documentVo.setFileVisitSite(fileLogInfo.getFileVisitSite());
            documentVo.setFileType(fileLogInfo.getFileType());
            documentVo.setFileSize(fileLogInfo.getFileSize());
            documentVo.setUploadTime(fileLogInfo.getUploadTime().toInstant(ZoneOffset.ofHours(8)).toEpochMilli());
            documentVo.setSourceType(fileLogInfo.getSourceType());
            documentVo.setDocSource(moduleVo.getIsCooperate() + 1);
            documentVo.setDocTitle(moduleVo.getMatterName());
            if (null != fileLogInfo.getFileGroup()) {
                documentVo.setFileGroup(fileLogInfo.getFileGroup().getName());
                documentVo.setStatus(agendaMatterService.isApprove(fileLogInfo.getEnterpriseId(), fileLogInfo.getFileGroup().name()) == 0?1:0);
            }else {
                documentVo.setStatus(1);
            }
            documentVo.setClassId(fileLogInfo.getClassId());
            documentVo.setClassName(sysFileClassService.getClassName(fileLogInfo.getClassId()));
            documentVo.setModuleVos(common.extract(moduleVo));
            params.add(documentVo);
        }

        // 2、同步到搜索引擎
        if (params.size() > 0){
            esDocumentService.saveEs(params);
        }
    }

处理方法:在事务方法中,提交事务的时候再发起异步消费

/**
     * 批量添加文件关联
     * @param fileModuleVo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ResultMsg fileRelevanceModule(List<FileModuleVo> fileModuleVo) {
        for (FileModuleVo moduleVo : fileModuleVo) {
            // 1、修改已上传的文件
            sysUserFileLogService.updateById(new SysUserFileLog(moduleVo.getFileLogId(), moduleVo.getSourceType(), moduleVo.getIsCooperate() + 1, moduleVo.getMatterName(), moduleVo.getFileGroup(), moduleVo.getClassId()));

            // 2、添加文件关联
            if (!moduleVo.getModalList().isEmpty()){
                List<SysFileRelevanceModule> modules = new ArrayList<>();
                for (ModalListVo modalListVo : moduleVo.getModalList()) {
                    SysFileRelevanceModule module = new SysFileRelevanceModule();
                    BeanUtils.copyProperties(moduleVo, module);
                    BeanUtils.copyProperties(modalListVo, module);
                    module.setRelevanceId(StringUtils.isNotBlank(moduleVo.getRelevanceId()) ? moduleVo.getRelevanceId():modalListVo.getAgendaMatterRelatableId());
                    module.setRelevanceName(StringUtils.isNotBlank(moduleVo.getRelevanceId()) ? moduleVo.getRelevanceName():modalListVo.getAgendaMatterRelatableName());
                    modules.add(module);
                }
                super.saveBatch(modules);
            }else{
                SysFileRelevanceModule module = new SysFileRelevanceModule();
                BeanUtils.copyProperties(moduleVo, module);
                super.save(module);
            }

        }
        // 同步搜索引擎
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCommit() {
                // 发送消息给MQ
                rabbitMQSend.fileLogUpload(fileModuleVo);
            }
        });
        return ResultMsg.success(fileModuleVo);
    }

提交事务的时候再使用MQ发起异步消费

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值