首页 > 解决方案 > 由于异常回滚后的Spring批量更新数据库状态

问题描述

在 Spring 批处理 Writer 中,我将数据库行状态从 0 更新为 1。如果发生任何异常,则更新为 2。但是由于 @transaction 回滚,我无法将状态更新为 2。

(我抛出异常来触发回滚)

@Override
@Transactional
public void write(List<? extends TestEntity> enityList) throws Exception {
    
    for(TestEntity testEntity : enityList) {
        try {
            
        
            testEntity.setStatus(2);
            testRepository.save(testEntity);
            testRepository.flush();
            
            testMethod(testEntity); (which throws exception)
        
        }catch (Exception exception) {              
            testEntity.setStatus(2);
            testRepository.save(testEntity);
        }
        
    }
}   



@Transactional
public void testMethod(TestEntity testEntity) throws Exception {

    try{

    //Some service call
    //...
    
    } catch(Exception e) {
            log.error("error", e);
            throw new Exception("exp");
    }

}

标签: spring-bootspring-batchspring-transactions

解决方案


具有 的方法@Transactional会在抛出异常时回滚事务。因此,如果异常是您的代码的预期且正常的流程,则不应抛出异常并返回某种结果对象或状态代码。

@Transactional
public void testMethodThatIsAllowedToFail(TestEntity testEntity) {
    try{
        //Some service call
    } catch(Exception e) {
        return Status.FAILURE; // enum you have to create
    }
    return Status.SUCCESS;
}

// spring batch writer
public void write(List<? extends TestEntity> enityList) throws Exception {
    [...]
    Status result = testMethod(testEntity); (which throws exception);
    if (result != Status.SUCCESS) {
        // do something with it
    }
    [...]
}

你也可以玩弄,@Transactional(propagation = Propagation.REQUIRES_NEW)但你必须认真考虑是否需要额外的交易。


推荐阅读