Вы описываете очень распространенную проблему.
Обычный подход к решению этой проблемы заключается в использовании Оптимистического управления параллелизмом .
Если это звучит как gobbledegook, это не так.Это довольно простая идея.Параллельная часть этого термина относится к тому факту, что с записанными данными происходят обновления, и эти обновления происходят одновременно.Возможно, много писателей.(Ваша ситуация - вырожденный случай, когда источником проблемы является один писатель, но это та же основная идея).Оптимистическая часть, о которой я расскажу через минуту.
Проблема
Возможно, что при наличии нескольких писателей часть чтения и записи в двух обновлениях чередуется,Предположим, у вас есть A и B, которые оба читают и затем обновляют одну и ту же строку в базе данных.A читает базу данных, затем B читает базу данных, затем B обновляет ее, затем A обновляет ее.Если у вас есть наивный подход, тогда «последняя запись» победит, и записи Б могут быть уничтожены.
Введите оптимистичный параллелизм.Основная идея состоит в том, чтобы предположить, что обновление будет работать, но проверьте.Вроде как доверяй, но проверяй подход к контролю над вооружениями несколько лет назад.Способ сделать это состоит в том, чтобы включить поле в таблицу базы данных, которое также должно быть включено в объект домена, которое обеспечивает способ отличить одну «версию» строки БД или объекта домена от другой.Простейшим является использование поля метки времени с именем lastUpdate, в котором хранится время последнего обновления.Существуют и другие, более сложные способы проверки согласованности, но поле метки времени подходит для иллюстрации.
Затем, когда писатель или средство обновления хочет обновить БД, он может обновлять только строку, для которой соответствует ключ (независимо от того, какой у вас ключ) , а также , когда совпадает lastUpdate.Это часть проверки.
Поскольку разработчики понимают код, я приведу немного псевдо-SQL.Предположим, у вас есть база данных блогов, с индексом, заголовком и текстом для каждой записи в блоге.Вы можете получить данные для набора строк (или объектов), например:
SELECT ix, Created, LastUpdated, Headline, Dept FROM blogposts
WHERE CONVERT(Char(10),Created,102) = @targdate
Этот тип запроса может извлечь все записи блога в базе данных за определенный день, месяц или что-то еще.
При простом оптимистическом параллелизме вы обновите одну строку , используя SQL следующим образом:
UPDATE blogposts Set Headline = @NewHeadline, LastUpdated = @NewLastUpdated
WHERE ix=@ix AND LastUpdated = @PriorLastUpdated
Обновление может произойти, только если индекс совпадает (и мы предполагаем,это первичный ключ), а поле LastUpdated совпадает с тем, которое было при чтении данных.Также обратите внимание, что вы должны обновлять поле LastUpdated при каждом обновлении строки.
Более строгое обновление может настаивать на том, что ни один из столбцов не был обновлен.В этом случае нет отметки времени вообще.Примерно так:
UPDATE Table1 Set Col1 = @NewCol1Value,
Set Col2 = @NewCol2Value,
Set Col3 = @NewCol3Value
WHERE Col1 = @OldCol1Value AND
Col2 = @OldCol2Value AND
Col3 = @OldCol3Value
Почему это называется «оптимистичным»?
OCC используется в качестве альтернативы удержанию блокировок базы данных, что является жесткимподход к сохранению данных.Блокировка БД может помешать любому читать или обновлять строку БД, пока она удерживается.Это, очевидно, имеет огромное значение для производительности.Таким образом, OCC смягчает это и действует «оптимистично», предполагая, что когда придет время обновлять, данные в таблице не будут обновлены за это время.Но, конечно, это не слепой оптимизм - вы должны проверить прямо перед обновлением.
Использование Optimistic Cancurrency на практике
Вы сказали, что используете .NET.Я не знаю, используете ли вы DataSets для доступа к данным, строго типизированные или нет.Но .NET DataSets, или, в частности, DataAdapters, включают встроенную поддержку OCC.Вы можете указать и вручную кодировать команду UpdateCommand для любого адаптера данных, и именно здесь вы можете вставить проверки согласованности.Это также возможно в среде разработки Visual Studio .
(источник: asp.net )
Если вы получите нарушение, обновление вернет результат, показывающий, что были обновлены нулевые строки. Вы можете проверить это в событии DataAdapter.RowUpdated . (Имейте в виду, что в модели ADO.NET есть разные DataAdapter для каждого вида базы данных. Ссылка есть для SqlDataAdapter, который работает с SQL Server, но вам потребуется другой DA для разных источников данных.)
В событии RowUpdated вы можете проверить количество затронутых строк, а затем предпринять некоторые действия, если счетчик равен нулю.
Резюме
Убедитесь, что содержимое базы данных не было изменено, прежде чем писать обновления. Это называется оптимистический контроль параллелизма .
Другие ссылки: