问题描述

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) throws BusinessException{
        saveData();
        if (repeatList.size() > 0 || errorList.size() > 0) {
            throw new BusinessException("下列箱号出现错误请检查!其他箱号已保存!\n" + repeatList + errorList);
        }
    }

    public void saveData() {
        if (list.size() > 0) {
            containerBaseMapper.insertList(list);
        }
    }

两个方法互不干扰,但当doAfterAllAnalysed抛出异常时就会导致saveData方法对数据库的操作回滚。
而在业务逻辑中,我会对传入的数据过滤,正确的数据保存,错误的数据通过抛出异常返回给前端。
但是事务的回滚就会导致一但抛出异常就无法对正常的数据进行保存操作了。

解决方案

首先,明确数据库的事务触发回滚发生在哪个类。
在调用上面两个方法的Service中发现了事务注解

@Service
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor
public class ContainerBaseService {
...

因此,是由于Service层配置的事务向下传播到了监听器中(上述两个方法的类),导致了数据库的回滚

具体解决
在监听器具体的调用方法上添加以下注解,用于新创建一个事务来单独处理此方法中发生的异常等,而不受外层事务的影响
具体解释:https://blog.csdn.net/liujiancheng521/article/details/83542388

@Transactional(propagation = Propagation.REQUIRES_NEW, noRollbackFor = {BusinessException.class, RuntimeException.class})
public void importData (MultipartFile file) throws IOException {

Q.E.D.


ALL WILL BE CLEAR