You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot中实现单条关联数据删除失败仅回滚当前记录

解决方案

核心思路是为每条待清理的卡片单独创建独立事务,这样某条处理失败时,仅回滚该条对应的事务,不影响其他卡片的清理流程。具体调整如下:

关键修改点

  • 移除方法上的@Transactional注解,避免外层大事务包裹所有操作
  • 将单条卡片的清理逻辑放入TransactionTemplate中,且每条卡片对应一个独立事务
  • 为单条卡片的处理添加异常捕获,出错时记录日志并继续处理下一条

调整后的代码

private void purgeCards(List<CardEntity> cardsTobePurge) {
    List<Long> nextCardsNumberToUpdate = getNextCardsWhichWillNotBePurge(cardsTobePurge);
    TransactionTemplate transTemplate = new TransactionTemplate(transactionManager);
    // 设置为REQUIRES_NEW,确保每条卡片的事务独立于其他操作
    transTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);

    for (CardEntity cardTobePurge : cardsTobePurge) {
        try {
            transTemplate.execute(status -> {
                Long nextCardNumberOfCurrent = cardTobePurge.getNextCard();
                if (nextCardsNumberToUpdate.contains(nextCardNumberOfCurrent)) {
                    CardEntity cardToUnlink = cardRepository.findByCardNumber(nextCardNumberOfCurrent);
                    unLink(cardToUnlink);
                }
                log.info(BATCH_TITLE + " Removing card Number : " + cardTobePurge.getCardNumber() + " with Id : "
                        + cardTobePurge.getId());
                
                // 关联数据删除
                List<CardHistoryEntity> historyEntitiesOfThisCard = cardHistoryRepository.findByCard(cardTobePurge);
                List<LogCreationCardEntity> logCreationEntitiesForThisCard = logCreationCardRepository
                        .findByCardNumber(cardTobePurge.getCardNumber());
                List<LogCustomerMergeEntity> logCustomerMergeEntitiesForThisCard = logCustomerMergeRepository
                        .findByCard(cardTobePurge);

                cardHistoryRepository.deleteAll(historyEntitiesOfThisCard);
                logCreationCardRepository.deleteAll(logCreationEntitiesForThisCard);
                logCustomerMergeRepository.deleteAll(logCustomerMergeEntitiesForThisCard);
                cardRepository.delete(cardTobePurge);
                
                return Boolean.TRUE;
            });
        } catch (Exception e) {
            // 记录错误日志,当前卡片事务自动回滚,不影响后续处理
            log.error(BATCH_TITLE + " Failed to remove card Number : " + cardTobePurge.getCardNumber() + " with Id : "
                    + cardTobePurge.getId(), e);
        }
    }
}

逻辑说明

  1. 独立事务控制:通过TransactionTemplate的PROPAGATION_REQUIRES_NEW传播行为,确保每条卡片的清理操作都在全新事务中执行,与其他卡片的事务完全隔离。
  2. 异常隔离:循环中为每条卡片的事务执行添加try-catch,当某条处理抛出异常时,该事务自动回滚,捕获异常并记录日志后,循环继续执行下一条卡片的清理。
  3. 保留原有业务逻辑:完整保留了你原本的关联数据处理、日志删除等逻辑,仅调整事务的作用范围以实现需求。

内容的提问来源于stack exchange,提问作者Amine Choukri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 16:42:50