Я думаю, что последовательность вызовов методов здесь следующая:
Метод 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;
}
}
Надеюсь, это поможет