Для использования оптимистической блокировки нужно определить, изменялись ли данные после их последнего извлечения, что называется
Первая основана на создании временной метки или уникального номера версии для каждой записи, которые изменяются при обновлении записи. Исходное значение или номер версии включаются в состав предложения WHERE в команде обновления.
Вторая стратегия заключается в сохранении исходных значений полей. Эти значения становятся дополнительными условиями предложения WHERE в команде обновления.
В обоих способах, если исходная запись изменена, условие предложения WHERE не удовлетворяется, запись не будет найдена и не будет обновлена.
При использовании оптимистической блокировки в модели ADO 2.X в случае нарушения параллельного доступа появляется сообщение о невозможности найти запись, а не о нарушении параллельного доступа.
В модели ADO.NET поддерживается только оптимистическая блокировка и в текущей версии нет встроенной поддержки пессимистической блокировки. В Visual Studio .NET предусмотрено несколько возможностей для реализации оптимистической блокировки. Эта поддержка находится в полном согласии с расширенной поддержкой распределенных, отключенных и асинхронных приложений.
Команды SQL UPDATE и DELETE, сгенерированные объектом CommandBuilder и программой-мастером Data Adapter Configuration Wizard, содержат предложение WHERE для определения конфликтов параллельного доступа. Рассмотрим более внимательно код из главы 6, "ADO.NET: объект DataAdapter", созданный с помощью программы-мастера Data Adapter Configuration Wizard. Для этого нужно открыть раздел кода с заголовком Windows Form Designer generated code (Код, сгенерированный конструктором Windows Form) в коде формы frmUpdates. Но сначала рассмотрим команду SQL UPDATE, которая приводится в листинге 7.1.
UPDATE tblEmployee
SET FirstName = @FirstName,
LastName = @LastName,
DepartmentID = @DepartmentID,
Salary = @Salary
WHERE
(ID = @Original_ID) AND
(DepartmentID = @Original_DepartmentID OR
@Original_DepartmentID IS NULL AND DepartmentID IS NULL)
AND (FirstName = @Original_FirstName)
AND (LastName = @Original_LastName)
AND (Salary = @Original_Salary OR
@Original_Salary IS NULL AND Salary IS NULL)
;
SELECT FirstName, LastName, DepartmentID, Salary, ID
FROM tblEmployee WHERE (ID = @ID)
Эта команда SQL выглядит как обычная команда UPDATE, которая задает новые значения для четырех обновляемых полей в качестве параметров объекта UpdateCommand. Предложение WHERE содержит первичный ключ (ID), а также исходные значения для каждого поля и проверяет их соответствие текущим значениям записи в базе данных. Более того, эта команда SQL проверяет наличие неопределенных значений NULL в базе данных и полях таблицы tblEmployee.
Команда SELECT (заданная при конфигурировании объекта DataAdapter) располагается вслед за командой UPDATE после точки с запятой. Точка с запятой всегда используется для разделения команд в пакете команд SQL, а команда SELECT добавляется по умолчанию для возвращения обновленной записи в приложение.
Рассмотрим код указания параметров для объекта UpdateCommand, как показано в листинге 7.2.
Me.SqlUpdateCommand1.Parameters.Add(New System.Data.SqlClient.SqlParameter("@FirstName", System.Data.SqlDbType.VarChar, 50, "FirstName"))
Me.SqlUpdateCommand1.Parameters.Add(New System.Data.SqlClient.SqlParameter("@LastName", System.Data.SqlDbType.VarChar, 70, "LastName"))
Me.SqlUpdateCommand1.Parameters.Add(New System.Data.SqlClient.SqlParameter("@DepartmentID", System.Data.SqlDbType.Int, 4, "DepartmentID"))