Здравствуйте, Poul_Ko, Вы писали:
P_K>Всем доброго
P_K>Сейчас озвучу проблему, наверняка я не первый кто с ней сталкивается и решения уже давно известны, но видимо они мне не попадались или не запомнились.
P_K>Речь идёт о задаче обеспечения неизменности состояния бизнес-объектов до конца бизнес-операции в многопользовательской среде.
P_K>Представим что есть какая-то операция, по бизнес правилам она может быть успешно выполнена только при определённом состоянии каких-то объектов. Как мы это реализуем? В коде сначала читаем эти объекты, проверяем их состояние, и если оно соответствует бизнес-правилам, то выполняем операцию. В многопользовательской среде здесь могут быть проблемы: состояние проверенных объектов может измениться между чтением объектов и выполнением операции, что по сути это приведёт к выполнению операции с нарушению бизнес-правил. Серьёзность такого нарушения может варьироваться — иногда это допустимо, а иногда нет (на одно место продано два билета).
P_K>Для избежания такой ситуации логично выполнять блокировку прочитанных объектов до конца операции так, чтобы никто другой не мог изменить их состояние.
P_K>Здесь не идёт речь о проверке состоянии самого изменяемого объекта — решение через "оптимистическую блокировку" известно. Я говорю о стабильности состояния других логически связанных сущностей, которые сами не изменяются операцией.
P_K>Первое решение, которое в принципе уже работает, это использование serializable-транзакций на базе. Здесь по сути все блокировки выполняет база. Масштабы и объём блокировок в базе в целом слабопредсказуемы, чтобы как-то на них повлиять надо плотно садиться за структуру базы и запросы.
P_K>У этого решения имеются ещё недостатки: появляются дедлоки по мере роста нагрузки и количества вовлечённых таблиц, не охватывает данные, которые не читаются из базы (находятся в кеше — справочники).
P_K>Какие другие решения можете посоветовать?
P_K>Писать свой менеджер блокировок? Есть примеры?
P_K>Технологии и архитектура: .NET, трёхзвенка Desktop Client — WCF services on IIS, EF — MS Sql Server, нет горизонтального масштабирования.
Смотри
блокировка с низкой степенью детализации.