我已经使用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;
}
我认为这里的方法调用顺序如下
[方法create()
开始事务并调用方法secModuleRepository.save(pData)
。
假设secModuleRepository.save(pData)
具有默认的交易传播REQUIRED
,它参与了以方法REQUIRED
开始的交易。
create()
毫无例外地返回,并通过save()
通知方法@AfterReturning
得到建议。
此事务在提交后将导致onSaveExecuted()
。这发生在该事务结束时,即控件退出方法DataIntegrityViolationException
时。
要在所有情况下记录create()
方法调用,建议类型应为save()
或@After
,并且该日志调用不应是可能在提交时回滚的事务的一部分。
以下代码使用@Around
启动新事务并插入日志。这个想法是要记录一个新的事务,并且给定的示例代码可以重复使用与问题共享的代码,可以根据需求进行改进。
TransactionTemplate
希望这会有所帮助