Skip to content

Commit

Permalink
flush
Browse files Browse the repository at this point in the history
  • Loading branch information
darkleaf committed Nov 8, 2018
1 parent 24e5694 commit dbd2a7d
Showing 1 changed file with 13 additions and 7 deletions.
20 changes: 13 additions & 7 deletions docs/02-design/06-persistence.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,23 +187,29 @@ Record отвечает за состояние, а Ref - за идентичн
Мы можем использовать 2 стратегии фиксации изменений: оптимистическую и пессимистическую.

В случае оптимистической стратегии мы можем воспользоваться паттерном Единица работы(Unit of Work).
При вызове `create` или `get-one` заполняется отображение
идентичности в ее начальное состояние.
Идентичность создается с помощью функций `create` или `get-one`.
При этом сохраняется отображение идентификатора на начальное состояние сущности.
При первом извлечении с помощью `get-one` мы так же запоминаем версию сущности.
При фиксации происходит сравнение начального состояния идентичностей с их текущим состоянием.
Открывается транзакция и если версии сущностей не изменились, то происходит фиксация в хранилище.
Отмечу, что при таком подходе мы на очень короткое время забираем соединение из пула.

В случае пессимистической стратегии мы можем при каждом изменении идентичности,
а для Ref можно задать
[наблюдателя](https://clojuredocs.org/clojure.core/add-watch),
производить соответствующие изменения в хранилище.
При этом транзакция хранилища длится столько же, сколько и бизнес-транзакция.

Конечно, предложенная схема работает только для выборок по первичному ключу.
Очень сложно реализовать Identity map имея возможность делать выборки по произвольным критериям.
Допустим, мы выбираем по идентификатору пользователя с ролью "Модератор" и меняем ее на роль "Админ".
В той же бизнес транзакции мы выбираем всех пользователей с ролью Модератор.
Должен ли первый пользователь попасть в выборку?
Если мы используем оптимистическую стратегию, то в рамках бизнес-транзакции мы
не можем делать выборки по произвольному ключу.
Допустим, мы выбираем пользователя по его идентификатору .
Оказалось, что ему 42 года. Установим его возраст равным 43.
В этой же бизнес-транзакции выберем всех пользователей с возрастом равным 42.
Очевидно, что перед выборкой необходимо
[сохранить](https://docs.jboss.org/hibernate/stable/core.old/reference/en/html/objectstate-flushing.html)
"грязные" сущности в БД,
чтобы запрос вернул то, что мы ожидаем.
Но у нас нет открытой транзакции уровня базы данных и мы не можем обеспечить изоляцию.

Мы можем воспользоваться Запросами(Query) и извлекать любые данные(состояние) вне транзакции
и перечитать данные находясь в транзакции:
Expand Down

0 comments on commit dbd2a7d

Please sign in to comment.