#java #spring #hibernate #spring-data-jpa
Вопрос:
Я столкнулся с проблемой с sping JPA @транзакцией (я думаю), ниже приведен минимальный код:
//package 1
@Transactional
public void method_m1(){
Result result = method_m2();
audit(result);
}
//package 2
@Transactional(propagation = Propagation.REQUIRED)
public Result method_m2(){
Result result = new Result()
//creating object say User(User mapped to database table users)
User u = new User();
// setting some attributes;
u = userRespositoy.save(user);
// tried with saveAndFlush no luck
result.set(u);
return result ;
}
//package 3
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void audit(Result result){
CompletableFuture.runAsync(
() -> {
//auditing user saving to db
User user = userRepository.findById(result.get().getId()).orElseThrow(() -> new
UserNotFoundException("user not found, userId :" result.get().getId()));
});
}
при получении вновь созданного пользователя по идентификатору пользователя из базы данных возникает исключение.
кто-нибудь может объяснить, пожалуйста, что здесь происходит?
Заранее признателен.
Комментарии:
1. Чтобы было понятно. Вы не можете найти пользователя по идентификатору, верно?
2. @SimonMartinelli — да, именно эта проблема
3. Изменение ТРЕБУЕТ обновления с ПОДДЕРЖКОЙ. REQUIRES_NEW создает новый сеанс БД, в котором ваши DML в других транзакциях еще не выполнены. И, кроме того, REQUIRES_NEW является одной из основных причин взаимоблокировок БД, поэтому его следует использовать очень осторожно.
4. Проблема в том, что RunAsync выполняется в другой транзакции и не видит созданную запись, поскольку транзакция может быть не завершена. Почему вы запускаете его асинхронно?
5. @SimonMartinelli — Я работаю асинхронно, потому что не хочу, чтобы ответ задерживался только из-за аудита..