Как добиться согласованности транзакций в ORM? - PullRequest
0 голосов
/ 16 октября 2019

Мой вопрос носит концептуальный характер.

Давайте предположим, что мы используем ORM (например, Entity Framework, Hibernate, ...) и моделируем наши доменные объекты в этих ORM. Поскольку ORM будет абстрагировать большинство транзакций SQL / do для нас, как мы можем быть уверены, что наши транзакции будут согласованными?

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

var book = books.Single(b => b.Id == 42);
book.Quantity -= 1;
books.SaveChanges();

Но если я правильно понял ORM, они будут только оборачивать изменение книги в запросе UPDATE. Это означает, что вы можете получить основные проблемы параллелизма, такие как: проблема параллелизма с ормами

Если вы будете использовать SQL, вы просто заключите в транзакцию .Quantity - = 1 и будете в безопасности.

Как бы вы обычно справлялись с этим надлежащим образом в ORM, или это обрабатывается как-то автоматически?

Ответы [ 2 ]

0 голосов
/ 16 октября 2019

Entity Framework использует для этого Оптимистичный параллелизм . И большинство систем РСУБД не будут предотвращать эту аномалию обновления при использовании транзакции.

UPDATE T SET Quantity = Quantity - 1 WHERE ID = :ID

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

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

0 голосов
/ 16 октября 2019

Вы должны сделать выбор для обновления, прежде чем изменить количество. Это заблокирует запись.

Это зависит от используемого вами ORM. С Hibernate вы можете установить LockModeType при выполнении запроса.

В Hibernate это будет LockModeType.PESSIMISTIC_WRITE

Подробнее о блокировке в документации Hibernate:

https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#locking

...