Правильная обработка вложенных транзакций в Hibernate - PullRequest
1 голос
/ 02 апреля 2020

Я уверен, что что-то упустил, но я точно не знаю, что ...

Предоставляю следующий фрагмент:

@Service
public class MyClass {
    private MyClass self;
    private UserRepository userRepository;
    private ApplicationContext applicationContext;

    @PostConstruct
    private void init() {
        self = applicationContext.getBean(MyClass.class);
    }

    @Transactional
    public void doA(User user) {
        ...
        if (condition) {
            self.doB(user);
            throw new SecurityException();
        }
        user.setRandomField("x");
        userRepository.save(user);
    }

    @Transactional(value = Transactional.TxType.REQUIRES_NEW)
    public void doB(User user) {
        ...
        userRepository.save(user);
    }
}

Что я знаю о @Transactional это то, что если он используется, избыточно вызывать repository.save(entity).

Что я пытаюсь сделать, это обработать сущность из транзакционного метода, и, если есть условие прерывания, вызвать новый метод (помеченный REQUIRES_NEW), который обновит некоторые поля объекта и сохранит его. Затем метод root (doA) вызывает исключение. К вашему сведению: @Transactional(dontRollbackOn = SecurityException.class) не является опцией в этой ситуации.

Для использования этого механизма фиксации вместо создания нового bean-компонента одним методом я просто вставил текущий bean-компонент в переменную, называемую self поэтому я могу использовать бин-прокси для управления транзакциями.

Странно то, что если я удаляю из doB вызов save, когда транзакция doA откатывается из-за SecurityException изменения, выполненные doB, также отменяются. Но если я впущу его туда, это сработает, как и ожидалось.

Я что-то делаю не так или я что-то упускаю?

Спасибо!

1 Ответ

1 голос
/ 02 апреля 2020

Старайтесь не передавать пользовательский экземпляр в doB (). Вместо этого передайте Id и прочитайте пользователя из репо изнутри. Я не уверен, как прикрепленная сущность обрабатывается между различными сессиями.

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