Уровень изоляции транзакций и Hibernate

116
27 октября 2021, 00:20

Первый вопрос. Какая связь существует между уровнем изоляции транзакций, параметрами JPA Lock.READ / Lock.WRITE и версиями @Version (Оптимистическая блокировка)? Я более менее понял по отдельности каждую из этих 3 разделов, но не понимаю, как они связаны между собой. Выбранный уровень изоляции транзакций дает некие «гарантии» при проведении операций с таблицами. Параметры Lock.READ/Lock.WRITE позволяют добиться блокировки полей таблицы при проведении операций. Если я правильно понял, для этого как раз и используются поле @Version. Но все таки не до конца улавливаю связь между эти тремя понятиями. Или они дополняют друг друга, или это разные способы решения одних и тех же проблем. В общем, буду очень благодарен за ответ или же ссылку, где можно прочесть информацию именно по вопросы связи между этими понятиями и их совместном использовании.

Второй вопрос. Каким способом в Hibernate можно указать требуемый уровень изоляции транзакции для конкретной транзакции? И принято ли так делать?

Спасибо.

Answer 1

Попробую ответить по порядку:

Как соотносятся Lock и уровни изоляции

  1. Уровень изоляции транзакций (transaction isolation level) - относится к чтению данных, но не к записи данных;
  2. Lock относится к доступу к данным (то есть затрагивает и чтение и запись и модификацию);
  3. Можно сказать так, что механизм Lock обеспечивает работоспособность различных уровней изоляции данных, в самом тупом примере: если у вас стоит уровень изоляции READ_COMMITTED, то вставка произведенная параллельной сессией будет локирована на запись пока сессия не выдаст commit(), но лок на чтение будет открыт сразу при запросе вашего select, а при REPEATABLE_READ оба лока (на чтение и запись) будут стоять до commit() - соответственно ваш select увидит результаты модификации только после коммита.

Каким способом в Hibernate можно указать требуемый уровень изоляции транзакции для конкретной транзакции?

Вообще это не сильно здорово. Уровень изоляции транзакций это принадлежность коннекта к БД, соответственно фактически изменение уровня изоляции равносильно переконнекту к БД, а насколько это дорогая операция вы сами можете оценить исходя из имеющейся у вас ситуации.

Тем не менее, если вы таки решили менять перед каждой транзакцией уровень изоляции транзакций, то самый простой способ это отправить в СУБД raw SQL query (любой ORM это поддерживает), типа:

ALTER SESSION SET ISOLATION_LEVEL SERIALIZABLE
Answer 2

Вопрос лёгкий, но ответ слишком длинный. Лучше книжки почитать.

Уровни изоляции, блокировки настоящие и оптимистические - работают каждый над своей проблемой. Прямо они не связаны. Подбирая их комбинацию, получаете то, что Вам нужно.

В jpa предусмотрены как оптимистичные режимы блокировки (полностью полагаются на @Version), так и пессимистичные (которые выполняются сервером базы данных):

OPTIMISTIC (он же READ)
OPTIMISTIC_FORCE_INCREMENT (он же WRITE)
PESSIMISTIC_READ
PESSIMISTIC_WRITE
PESSIMISTIC_FORCE_INCREMENT

Как изменить уровень изоляции.
Если управляете транзакцией самостоятельно, то и меняйте как хотите (сonnection.setTransactionIsolation? Нужно только connection извлечь из entity из managera). А например JTA изменить вряд ли получится. Там уровень задаётся в конфигурации datasource и изменение его не предполагается. Кажется именно так. Хотя можете уточнить этот момент. Всё течёт, всё изменяется. Может это уже не так.

Answer 3

Некоторую информацию по данному вопросу можно почерпнуть из статьи с хабра

UPD по второму вопросу: Аннотация @Transactional указывает, что метод должен выполняться в транзакции. Менеджер транзакций открывает новую транзакцию и создаёт для неё экземпляр Session, который доступен через sessionFactory.getCurrentSession(). Все методы, которые вызываются в методе с данной аннотацией, также имеют доступ к этой транзакции, потому что экземпляр Session является переменной потока (ThreadLocal). Вызов sessionFactory.openSession() откроет совсем другую сессию, которая не связана с транзакцией.

Параметр rollbackFor указывает исключения, при выбросе которых должен быть произведён откат транзакции. Есть обратный параметр — noRollbackFor, указывающий, что все исключения, кроме перечисленных, приводят к откату транзакции.

Параметр propagation самый интересный. Он указывает принцип распространения транзакции. Может принимать любое значение из перечисления org.springframework.transaction.annotation.Propagation.

  • Propagation.REQUIRED — выполняться в существующей транзакции, если
    она есть, иначе создавать новую.
  • Propagation.MANDATORY — выполняться в существующей транзакции, если она есть, иначе генерировать
    исключение.
  • Propagation.SUPPORTS — выполняться в существующей
    транзакции, если она есть, иначе выполняться вне транзакции.
  • Propagation.NOT_SUPPORTED — всегда выполняться вне транзакции. Если
    есть существующая, то она будет остановлена.
  • Propagation.REQUIRES_NEW — всегда выполняться в новой независимой транзакции. Если есть существующая, то она будет остановлена до окончания выполнения новой транзакции.
  • Propagation.NESTED — если есть текущая транзакция, выполняться в новой, так называемой, вложенной транзакции. Если вложенная транзакция будет отменена, то это не повлияет на внешнюю транзакцию; если будет отменена внешняя транзакция, то будет отменена и вложенная. Если текущей транзакции нет, то просто создаётся новая.
  • Propagation.NEVER — всегда выполнять вне транзакции, при наличии существующей генерировать исключение.
READ ALSO
Переписать SQL запрос в HQL

Переписать SQL запрос в HQL

Необходимо переписать запрос

81
bootstrap выравнивание нескольких таблиц

bootstrap выравнивание нескольких таблиц

ищу помощи по правильному формированию списков характеристик товара, остановился на отображении в виде таблицы, однако имею неприятность...

116
Съезжает элемент в CSS

Съезжает элемент в CSS

при выборе вариативного товара в woocommerce, надпись очистить неправильно отображается, плывет https://apphoneru/product/iphone-xs-max-512gb-zolotoj/ хотя вот на этом...

99
Как в Flask отобразить Excel в браузере

Как в Flask отобразить Excel в браузере

Приложение формирует эксель-файл и сохраняет файл в папке на сервереНеобходимо отобразить его в браузере (т

121