Spring中带有AOP @AfterReturning的UnexpectedRollbackException

问题描述 投票:0回答:1

我已经使用Spring AOP为每个保存操作设置了一个日志记录,并在其中标记了@Transactional。问题是当我的save方法抛出异常并仅使用回滚标记事务时,但是使用AOP的日志记录操作却不知道。这就是为什么导致:

'事务默默地回滚,因为它已被标记为仅回滚'。

如何克服这种情况?

我的保存方法:

@Transactional
public void create(SecModuleRequest secModuleRequest) {
  SecModule secModule = secModuleRepository.save(pData); // throw data integrity exception
}

我的记录方式:

@Transactional
@AfterReturning(value = "execution(public * save(..)) && this(org.springframework.data.repository.CrudRepository)", returning = "responseEntity")
public void onSaveExecuted(JoinPoint pjp, Object responseEntity) {
    try {            
        ...            
        insertAuditLog(jsonStr, entityActionLog.getQueryClauseExt());
    } catch (Exception ex) {
      ex.printStackTrace();
    }
}

public int insertAuditLog(String auditContent, String queryRowId) {
    String sql = " Insert into LOG (LOG_ID,LOG_DATETIME, LOG_CONTENT) " +
            "           values (LOG_SEQ.NEXTVAL, SYSDATE, ?) ";
    Query query = entityManager.createNativeQuery(sql);
    query.setParameter(1, auditContent);        
    int resultInsert = query.executeUpdate();
    return resultInsert;
}
java spring-boot spring-data-jpa spring-aop
1个回答
0
投票

我认为这里的方法调用顺序如下

[方法create()开始事务并调用方法secModuleRepository.save(pData)

假设secModuleRepository.save(pData)具有默认的交易传播REQUIRED,它参与了以方法REQUIRED开始的交易。

create()毫无例外地返回,并通过save()通知方法@AfterReturning得到建议。

此事务在提交后将导致onSaveExecuted()。这发生在该事务结束时,即控件退出方法DataIntegrityViolationException时。

要在所有情况下记录create()方法调用,建议类型应为save()@After,并且该日志调用不应是可能在提交时回滚的事务的一部分。

以下代码使用@Around启动新事务并插入日志。这个想法是要记录一个新的事务,并且给定的示例代码可以重复使用与问题共享的代码,可以根据需求进行改进。

TransactionTemplate

希望这会有所帮助

© www.soinside.com 2019 - 2024. All rights reserved.