Я работаю над большим приложением, которое управляет сложными «событиями» с небольшим количеством данных.
Приложение разбито на клиента (в основном C #, в основном .NET 2.0), сервер на основе WCF, предназначенный для работы на IIS (веб-службы на этом уровне), и серверную часть данных, основанную на NHibernate с MS SQL Server. база данных.
Мы столкнулись с ошибкой по следующему сценарию:
Несколько пользователей (в нашем случае 6, в нашем тестировании) одновременно сохраняют постоянный объект (например, событие) на клиенте. (Это делается посредством словесного обратного отсчета, поэтому мы говорим о разнице в секунду или около того из-за времени реакции)
Когда они сохраняют объекты на клиенте, клиент вызывает сервер для сохранения этого объекта. Сервер выполняет любую необходимую бизнес-логику, а затем фиксирует изменение через NHibernate.
В этой ситуации (многократное сохранение по вызовам службы) некоторые клиенты возвращаются с неискаженным исключением:
"Строка была обновлена или удалена другой транзакцией"
Что является исключением из NHibernate.
В своем исследовании я обнаружил несколько случаев этой ошибки, но она всегда была последовательной. Наше приложение работает последовательно, это происходит только при одновременном сохранении.
Как защитить несколько одновременных транзакций NHibernate друг от друга?
(Это будет приложение большого объема, поэтому минимально необходимая блокировка хороша. Мы не можем позволить себе вообще блокировать все сохранения.)
Существуют ли настройки NHibernate, которые бы это делали? Нужно ли нам заранее определять блокировку на стороне сервера? Может ли база данных справиться с этим, возможно, с другими настройками защиты транзакций?
Это медведь для тестирования, как и большинство проблем с потоками, отсюда и исследовательский / теоретический подход. Какой опыт у такой архитектуры?
Редактировать: Дополнительная информация и теория.
Кажется, что изменение значений, которые находятся непосредственно в таблице как основной объект, не вызвало этой проблемы, в то время как изменение элементов, к которым осуществляется доступ через объединение, произошло. (В данном случае набор атрибутов).
Наша рабочая теория, которая, кажется, соответствует этой ситуации, следующая:
Несколько сохранений приходят для одного и того же события. Каждый получает копию существующего события (для изменения). Первые, чтобы сохранить, в порядке. Более поздние, однако, имеют обновления, такие как добавление или удаление атрибутов (которые являются таблицей соединений), и обнаруживают, что добавление или удаление, которые необходимо выполнить, уже выполнено, и выручает, потому что другая транзакция отредактировала событие.
Как мы должны синхронизировать эти события?