Hibernate - транзакции: согласованность между двумя учетными записями - PullRequest
0 голосов
/ 12 октября 2018

Как поддерживать согласованность между транзакциями в Hibernate, например, у меня есть такой сценарий -

У меня есть две транзакции, T1 и T2, обе одновременно работают на одной учетной записи A (начальное значение = 500), T1 хочет сделать 200 сложение и T2 хочет минус 100 с A.Если транзакция происходит следующим образом -

1. T1 reads value of A as 500, T2 reads value of A as 500.
2. T1 does A = 500 + 200.
3. T2 does A = 500 -100.
4. T2 commits value of A as 400.
5. T1 commits Value of A as 700.

Конечное значение A будет 700, что неверно . Правильное значение A должно быть 600.

Как это можно исправить?

  • A = Account, означает Tuple, т.е. строкув таблице СУБД.Здесь он представляет банковский счет, который однозначно идентифицируется номером счета.

1 Ответ

0 голосов
/ 12 октября 2018

Вы можете использовать две стратегии.

Первая - это оптимистическая блокировка.Это позволяет выявлять такого рода ситуации и разрешать их путем сбоя второй транзакции.Это означает, что

T1 фиксирует значение A как 700.

приводит к javax.persistence.OptimisticLockException.Чтобы реализовать эту стратегию, вы должны создать специальный столбец в сущности A, представляющий версию текущего кортежа, и добавить к ней аннотацию javax.persistence.Version.После каждой фиксации провайдер Jpa будет автоматически увеличивать столбец версии и проверять его значение при каждой фиксации следующим образом:

1. T1 reads value of A (v1) as 500, T2 reads value of A (v1) as 500 .
2. T1 does A = 500 + 200.
3. T2 does A = 500 -100.
4. T2 commits value of A as 400 - db and entity versions are the same
5. T1 commits Value of A (v1) as 700 - version mismatch: db version is v2 and current version is v1 -> OptimisticLockException

Вторая стратегия - это пессимистическая блокировка (эксклюзивная блокировка): она разрешает первую транзакцию (T1 из вашегопример), чтобы заблокировать Tuple от чтения \ записи его из другой транзакции, пока он не снимет блокировку при коммите \ откате.Вы можете добиться этого, вызвав javax.persistence.EntityManager#lock с javax.persistence.LockModeType#WRITE в качестве второго аргумента.

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