Потерянное обновление в ADO.NET и DataSets - PullRequest
3 голосов
/ 26 октября 2011

У меня есть два экземпляра класса с именем User. Каждый из этих объектов имеет свой собственный DataSet, SQLiteConnection, SQLiteDataAdapter и т. Д. Я пытаюсь смоделировать аномалию «Lost Update» для школьной работы.

Таблица базы данных выглядит следующим образом:

ID    Name     Salary
---------------------
1     John     10

Наборы данных заполняются при построении объектов User. Каждый из этих объектов обновляет одну и ту же строку. Первый объект увеличивает зарплату с идентификатором строки 1 на 2, что приводит к 12. Второй объект также увеличивает зарплату на 5, что приводит к 15, однако мы ожидали 17, или, по крайней мере, исключение, следовательно, откат транзакции. Но никаких исключений не происходит. Что я делаю не так?

Вот код обновления, который у меня есть в User классе

public bool IncreaseSalary(int raise) 
{
    int currentSalary = Convert.ToInt32(_dataSet.Tables["Employees"].
        Rows[0]["Salary"]);
    _dataSet.Tables["Employees"].Rows[0]["Salary"] = currentSalary + raise;

    _connection.Open();
    SQLiteTransaction transaction = _connection.BeginTransaction();
    _employeesDataAdapter.SelectCommand.Transaction = transaction;
    _employeesDataAdapter.UpdateCommand.Transaction = transaction;
    _employeesDataAdapter.DeleteCommand.Transaction = transaction;
    _employeesDataAdapter.InsertCommand.Transaction = transaction;

    int result = _employeesDataAdapter.Update(_dataSet);

    transaction.Commit();

    _dataSet.Clear();
    _employeesDataAdapter.Fill(_dataSet);

    return result > 0;
}

1 Ответ

0 голосов
/ 26 октября 2011

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

...
myAdapter.UpdateCommand = new SQLiteCommand("UPDATE Dept SET DeptNo = :DeptNo, DName = :DName WHERE DeptNo = :oldDeptNo", sqConnection); 
myAdapter.UpdateCommand.Parameters.Add("DeptNo", SQLiteType.Int32, 0, "DeptNo"); 
myAdapter.UpdateCommand.Parameters.Add("oldDeptNo", SQLiteType.Int32, 0, "DeptNo").SourceVersion = DataRowVersion.Original;
...

После вызова обновления проверьте, сколько записей было затронуто;если нет, то это потерянное обновление .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...