Подтвердить что ты не робот

Перехватить транзакцию только тогда, когда она обязательно будет совершена, но до совершения

Контекст - это 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

4b9b3361

Ответ 1

Я просто хочу сначала вернуться к транзакции, будучи частью работы, которая либо проходит, либо все терпит неудачу. С тем, что вы говорите о своем методе, о том, что он не может быть откат и должен выполняться между началом и концом транзакции, тогда мне жаль, что у вас нет транзакции.

Вы можете сделать много проверок в своем методе, чтобы убедиться, что вероятный откат отката чрезвычайно тонкий, но всегда будет шанс, что ваш метод будет выполнен и произойдет откат, но этот шанс может быть крайне незначительным и вы можете быть довольны этим, я не знаю.

Edit: Я думаю, что аналогия была бы приятной.

Случай 1: Таким образом, классический пример сделки заключается в покупке банана в магазине, если у вас нет денег, или в магазине нет банана, в магазине нет денег, вы не получаете банан, это то, что обычно происходит. Но если все условия установлены, транзакция будет успешно выполнена.

Случай 2: Теперь о том, что вы просите. Для аргументов давайте скажем, что вы вор, и вы только хотите украсть банан, если вам это удастся. Вы не можете это знать наверняка, потому что вы спрашиваете о будущем, если вы не гадалка, когда вы идете украсть банан, вас могут поймать.

Если вы вернетесь к первому делу, вы можете проверить, что у вас есть деньги, в магазине есть банан, дайте магазину свои деньги, бросьте всех клиентов, запереть двери в магазин, чтобы магазин был в неизменное состояние. Иди, делай свой метод, который нельзя откат, вернуться в магазин и взять банан. Никто не может заверить вас, что банан все еще будет там, но это очень вероятно.

Ответ 2

В вашем случае один из ваших ресурсов несовместим с двухфазным фиксацией (не с поддержкой XA). Ваша идея идет в направлении шаблона, описанного в параграфе XA и Last Resource Gambit http://www.javaworld.com/article/2077963/open-source-tools/distributed-transactions-in-spring--with-and-without-xa.html

Использование последнего ресурсного гамбита вкратце объяснено в ответе Как настроить Spring Boot + Bitronix + non-XA Datasource + XA JMS Connection

Кстати, в вашем вопросе не упоминается, какую реализацию управляющего транзакций вы используете (JBossTS, Bitronix JTA, Atomicos Transaction Essentials,...).