Контекст - это Java - JPA с Hibernate и Spring.
Возьмем сценарий двухфазного протокола фиксации (но только с одним ресурсом):
-
Запрос для фиксации из приложения
-
Голосовать Да/Нет (из базы данных в нашем случае)
3,1. Если да из базы данных
3.1.1. (Сделать обратный вызов в коде) - не является частью протокола
3.1.2. Commit to database
3.2 Если no
3.2.1 Откат к базе данных
То, что я хочу, - это способ сделать обратный вызов из 3.1.1 в коде, но только тогда, когда известно, что транзакция будет совершена, но до того, как это действительно произойдет. Кроме того, если здесь вызывается исключение, транзакция должна быть отменена.
Используя TransactionSynchronization
(*) из Spring, вы можете перехватить транзакцию до ее совершения/завершения или после ее совершения/завершения.
-
beforeCommit()
обратный вызов говорит, что откат может все еще возникать после вызова метода; -
beforeComplete()
вызывается, даже если транзакция терпит неудачу. -
afterCommit/Complete()
вызывается после того, как транзакция фактически была привязана к базе данных, и нет возможности отката.
Теперь, когда я выгляжу, кажется, что я хочу другой в полном двухфазном протоколе фиксации; но мне интересно, есть ли обходной путь в Spring. Разница в том, что вызов, выполняемый в обратном вызове, нельзя отменить.
(*) из Spring 4.2 очень прост с @TransactionalEventListener
и TransactionPhase
, который прекрасно абстрагирует TransactionSynchronization