gpt4 book ai didi

java - Spring 中使用 AOP @AfterReturning 出现意外的RollbackException

转载 作者:行者123 更新时间:2023-12-01 16:59:12 24 4
gpt4 key购买 nike

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

'Transaction silently rolled back because it has been marked as rollback-only'.

如何克服这种情况?

我的保存方法:

@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 ,它参与使用 create() 方法启动的事务。

save() 返回,没有任何异常,并由 @AfterReturning 建议方法 onSaveExecuted() 获取建议。

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

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

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

@Aspect
@Component
public class TxnAspect {

@PersistenceContext
private EntityManager entityManager;

// single TransactionTemplate shared amongst all methods in this instance
private final TransactionTemplate transactionTemplate;

// use constructor-injection to supply the PlatformTransactionManager
public TxnAspect(PlatformTransactionManager transactionManager) {
this.transactionTemplate = new TransactionTemplate(transactionManager);
}

@Around(value = "execution(public * save(..)) && this(org.springframework.data.jpa.repository.JpaRepository)")
public Object onSaveExecuted(ProceedingJoinPoint pjp) throws Throwable {
Object responseEntity = null;
try {
responseEntity = pjp.proceed();
} finally {
//gather the details and log
executeInNewTxn("log1","log2");
}
return responseEntity;
}

public Object executeInNewTxn(String str1, String str2) {
transactionTemplate.setPropagationBehavior(Propagation.REQUIRES_NEW.value());
return transactionTemplate.execute(new TransactionCallback<Object>() {
// the code in this method executes in a transactional context
public Object doInTransaction(TransactionStatus status) {
return insertAuditLog(str1, str2);
}
});
}

public int insertAuditLog(String auditContent, String queryRowId) {
String sql = " Insert into LOG (LOG_ID,LOG_DATETIME, LOG_CONTENT) "
+ " values (100, SYSDATE, ?) ";
Query query = entityManager.createNativeQuery(sql);
query.setParameter(1, auditContent);
int resultInsert = query.executeUpdate();
return resultInsert;
}
}

希望这有帮助

关于java - Spring 中使用 AOP @AfterReturning 出现意外的RollbackException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61538121/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com