Данные Spring: JPA и вложенная транзакция - PullRequest
0 голосов
/ 18 февраля 2019

У меня проблема с данными Spring JPA и вложенными транзакциями.Ниже приведены два метода вложенной транзакции моего сервиса.

@Service
public UserService {

    @Transactional
    public User createUser(UserDto userDto) {
        ....
        user = saveUser(user);
        sendEmail(user);
        ....
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public User saveUser(User user) {
        return userRepository.save(user);
    }

Бывает, что существует один сценарий, когда метод userRepository.save () должен генерировать исключение, но почему-то не генерируется, похоже, что он ожидает завершения родительской транзакции.Я ожидал, что исключение будет сгенерировано в методе saveUser, а метод sendEmail даже не будет выполнен.

Поскольку метод UserService.saveUser имеет распространение, установленное на Propagation.REQUIRES_NEW Я ожидал, что транзакция будет зафиксирована (оператор SQL, который должен быть выполнен) и любое исключение, которое распространяется.

Я не настроил ничего, связанного с транзакцией, поэтому я считаю, что режим сброса установлен на AUTO.

Может кто-нибудь определить, чтоя делаю неправильно или в чем мое заблуждение?

1 Ответ

0 голосов
/ 18 февраля 2019

Это потому, что вы вызываете метод @Transactional из одного и того же компонента.

@Transactional работает только с методами, вызванными для прокси, созданных Spring.Это означает, что когда вы создаете @Service или другой компонент, метод, вызываемый извне, будет транзакционным.Если вызывается из bean-компонента, ничего не произойдет, так как он не проходит через прокси-объект.

Самое простое решение - переместить метод в другой @Service или bean-компонент.Если вы действительно хотите сохранить его в том же компоненте, то вам нужно вызвать его, чтобы он был обернут в прокси с помощью Spring AOP.Вы можете сделать это следующим образом:

private YourClass self;

@Autowired
private ApplicationContext applicationContext;

@PostConstruct
public void postContruct(){
    self = applicationContext.getBean(YourClass.class);
}

Тогда вызов метода self приведет к открытию транзакции.

Другими словами: вы не испытываете ни одного из этиханомалии, потому что @Transactional сверх saveUser не работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...