2011-10-26 2 views
3

User이라는 클래스 인스턴스가 두 개 있습니다. 이러한 각 개체에는 자체 DataSet, SQLiteConnection, SQLiteDataAdapter 등이 있습니다. 학교 일을 위해 여기에서 "잃어버린 업데이트"예외를 시뮬레이트하려고합니다.ADO.NET 및 DataSets에서 손실 된 업데이트

데이터베이스 테이블은 다음과 같습니다

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

데이터 세트가 User의 건설에 가득합니다. 이러한 각 개체는 동일한 행을 업데이트합니다. 첫 번째 객체는 행 ID 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; 
} 
+0

"잃어버린 업데이트 이상"을 시뮬레이트하려는 경우이를 달성했습니다. 기본적으로 분실 된 업데이트는 여러 항목 (항목, 개체 등)이 동일한 단일 항목 (이 경우 데이터베이스 행)을 업데이트하려고한다는 것을 의미합니다. 해당 항목의 마지막 업데이트가 설정되어 있습니다. 따라서 두 번째 'User' 개체가 마지막으로 업데이트를 수행 한 것이므로 급여는 15 세가 아니라 17 세입니다. 이것이 당신이 요구하는 것을 설명하는지 확실하지 않은가요? –

+0

@JasonEvans 감사합니다. 그래, 나는 이상을 달성했다고 생각한다. 하지만 이제는 이런 일이 일어나지 않도록 방지하고 코드의 상황을 어떻게 처리 할 수 ​​있는지 보여 주어야합니다. –

+0

흠, 솔직히 말하면, 당신이 거래를 사용하는 것처럼 보입니다. 아마도 하나의 객체 만 데이터베이스를 업데이트 할 수 있도록 코드를 다시 설계해야할까요? 이것이 받아 들일 수 없다면 ADO.NET의 '비관적 잠금'전략을 조사해야합니다. 죄송합니다 더 도움이 될 수 없습니다. –

답변

0

이 코드 당신은 낙관적 동시성을 채용 할 수있다. 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; 
... 

업데이트를 호출 한 후 영향을받은 레코드 수를 확인하십시오. 없으면 업데이트가 손실 됨입니다.