Spring Boot项目手动提交事务案例

发布时间 2023-09-07 14:17:28作者: -西门-

Spring Boot项目手动提交事务案例

	// 注入 PlatformTransactionManager 对象,用于管理事务
    @Resource
    private PlatformTransactionManager transactionManager;

	public void addChatMomentTask(AddChatMomentTaskDTO dto) {
        // 创建一个默认的事务定义对象  
        TransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
        // 获取一个新的事务状态
        TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);
        // 如果发生异常,这个对象也需要保存入库并记录异常原因
        ChatMomentTask momentTask = ChatMomentTask.builder()
                .momentId(ObjectId.next())
                .taskName(dto.getTaskName())
                .createBy(ThreadLocalUtils.getUserCode()).build();
        baseMapper.insert(momentTask);
    	// 发生异常时需要回滚的数据
        if (CollectionUtil.isNotEmpty(dto.getAttachments())) {
            LinkedList<ChatAttachment> chatAttachments = new LinkedList<>();
            dto.getAttachments().forEach(item -> {
                ChatAttachment attachment = ChatAttachment.builder().attachmentId(ObjectId.next()).businessId(momentTask.getMomentId()).build();
                BeanUtil.copyProperties(item, attachment);
                chatAttachments.add(attachment);
            });
            chatAttachmentService.saveBatch(chatAttachments);
        }
        try {
            // 调用可能产生异常的方法
            this.sendChatMomentTask(momentTask.getMomentId());
            // 没有异常,提交当前的事务
            transactionManager.commit(transactionStatus);
        } catch (Exception e) {
            // 发生异常,回滚当前事务,之前的数据就都不落库了
            transactionManager.rollback(transactionStatus);
            log.error("addChatMomentTask error -> " + e.getMessage(), e);
            // 重新获取新的事务状态
            transactionStatus = transactionManager.getTransaction(transactionDefinition);
            // 给对象里存入异常原因
            momentTask.setFailResult(e.getMessage());
            // 再次插入数据库
            baseMapper.insert(momentTask);
            // 再次提交事务,保存数据落库
            transactionManager.commit(transactionStatus);
            throw new RuntimeException(e.getMessage());
        }
    }