Как реализовать постоянную блокировку без JPA? - PullRequest
1 голос
/ 10 февраля 2020

Я работаю над Java проектом Spring-Boot API, для которого уровень базы данных не будет использовать JPA для большинства объектов (из-за выбранного дизайна базы данных, который я не смог реализовать в JPA: [модель базы данных] и по которой я несколько дней поднимал еще один вопрос go: [вопрос] ).

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

Какие общие подходы люди использовали для реализации до JPA и Hibernate?

Ответы [ 2 ]

4 голосов
/ 10 февраля 2020

Для блокировки пессимистичности c JPA, наконец, сводится к использованию JDB C для выдачи select * from foo where id = 1 for update (в случае MySQL), который блокирует строку идентификатора 1. Никто не может выбрать эту строку до завершения транзакции, которая блокирует эту строку (см. Также this , который , выбранный для обновления , может в некоторых случаях заблокировать всю таблицу). Таким образом, вы можете убедиться, что только один парень может изменить эту строку.

Для оптимизации c блокировка JPA, наконец, сводится к первому введению номера версии для каждой записи. Всякий раз, когда выбирается запись, он также выбирает этот номер версии (предположим, что выбранная версия равна 10). И всякий раз, когда производится обновление, оно всегда увеличивает эту версию на единицу и проверяет, что версия все еще не изменена другим, используя следующее условие AND:

update foo set bar = xxxx , version = version + 1 where id = 1 and version = 10;

Итак, если никакие записи не могут быть обновленным, это означает, что другой парень уже изменил эту запись до того, как вы обновите ее (т. е. тот парень уже обновил версию до 11, в результате чего условие AND не выполняется) Вы можете просто показать некоторые сообщения об ошибках пользователю и попросить их перезагрузить / повторить попытку и т.д. c. в зависимости от требований вашего бизнеса.

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

1 голос
/ 10 февраля 2020

Для простоты используйте сериализуемую блокировку транзакций. Это проще, чем блокировка, подобная версии, и решает большинство проблем.

START TRANSACTION;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-- do stuff
COMMIT;

Spring Framework упрощает задачу, предоставляя аннотацию @Transactional, в которой можно указать уровень изоляции, а также стратегию распространения. Я считаю его чрезвычайно полезным и простым в использовании.

EDIT : MySQL Аврора (AWS RDS) не поддерживает сериализуемый уровень изоляции транзакций, поэтому используйте его с осторожностью.

В случае, если этого недостаточно, обратитесь к ответу @Ken Chan. По вашему вопросу ваше беспокойство concurrent edit of the entities, так что это должно сработать.

...