Spring:Caught EmptyResultDataAccessException导致整个事务回滚

时间:2017-03-10 13:52:56

标签: java spring transactions spring-jdbc spring-transactions

我有两种方法如下所示。

@Transactional
public void methodA(){
    logger.trace("Executing methodA");
    methodB()
    logger.trace("Executing methodA completed");
}

public void methodB(){
    //other codes here
    try{
        staffDao.queryById(1)   //Fetch a record from database
    }catch(EmptyResultDataAccessException e){
        logger.trace("Staff does not exists")
    }
    //other codes here
}

EmptyResultDataAccessException内发生methodB()时 ,methodA()上启动的整个交易将通过以下异常

进行回滚
  

org.springframework.transaction.UnexpectedRollbackException:   事务已回滚,因为它已标记为仅回滚

我知道这是spring @Transactional注释的默认行为。

就我而言,即使有EmptyResultDataAccessException,我也需要提交交易。由于EmptyResultDataAccessExceptionRuntimeException,我无法使用noRollBackFor注释的@Transactional属性。

有人可以建议解决方案吗?

2 个答案:

答案 0 :(得分:0)

我还没有密切关注您的代码,但如果您只是需要一种不回滚特定异常的事务的方法,您可以在@Transactional注释中标记该代码。

@Transactional(noRollbackFor = {EmptyResultDataAccessException.class})
public void methodA(){
.
.
}

http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/Transactional.html#noRollbackFor--

答案 1 :(得分:0)

查看SimpleJpaRepository中deleteById的代码

public void deleteById(ID id) {
    Assert.notNull(id, "The given id must not be null!");
    this.delete(this.findById(id).orElseThrow(() -> {
        return new EmptyResultDataAccessException(String.format("No %s entity with id %s exists!", this.entityInformation.getJavaType(), id), 1);
    }));
}

我认为这只是一种方便的方法。如果我不希望出现异常,则可以按照需要的方式实现它:

repo.findById(id).ifPresent(repo::delete);