Рассмотрим сначала зависимую вложенную транзакцию, создаваемую через getTransaction()
:
link:../../../../../../source/middleware/transactions_4.java[role=include]
-
загружаем сущность, где name == "old name"
-
указываем новое значение для поля
-
вызываем метод, создающий вложенную транзакцию
-
получаем тот же экземпляр EntityManager, что и в methodA
-
загружаем сущность с тем же идентификатором
-
значение поля новое, так как мы работаем в том же persistent context, и запросов к БД не было
-
commit в этот момент не происходит
-
изменения сохраняются в БД, в них будет содержаться "name B"
Теперь рассмотрим тот же самый пример с независимой вложенной транзакцией, создаваемой через createTransaction()
:
link:../../../../../../source/middleware/transactions_5.java[role=include]
-
загружаем сущность, где name == "old name"
-
указываем новое значение для поля
-
вызываем метод, создающий вложенную транзакцию
-
создаём новый экземпляр EntityManager, т.к. это новая транзакция
-
загружаем сущность с тем же идентификатором
-
значение поля старое, так как из БД загружен старый экземпляр сущности
-
изменения сохраняются в БД, значение "name B" теперь будет храниться в БД
-
из-за оптимистичной блокировки выбрасывается исключение, commit не выполняется
В последнем случае исключение в точке (8) возникнет, только если сущность является оптимистично блокируемой, т.е. если она реализует интерфейс Versioned
.