1

私が抱えている問題はこれです:

次のフィールドを持つテーブル(単なる例)があります。

ID int
Value int

次のことを行う IncreaseByFive() というメソッドがあります。

method IncreaseByFive(int ID)
{    
    int value = GetValueFromDB(ID);
    value = value + 5;
    SaveValueToDB(value, ID);    
}

私が避けたいのは、次の状況です。

  1. ユーザー A がメソッドを呼び出し、値を取得します (現在は 5)
  2. ユーザー B がメソッドを呼び出して値を取得します (現在は 5)
  3. ユーザー A が値を 5 増やします (現在は 10)
  4. ユーザー B が値を 5 増やします (現在は 10)
  5. ユーザー A が値を保存 (10)
  6. ユーザー B は値を保存します (10)

これで、レコードの値が 15 になるはずが 10 になりました。

私が強制したいのは次のとおりです。

  1. ユーザー A がメソッドを呼び出し、値を取得します (現在は 5)
  2. ユーザー B はメソッドを呼び出しますが、A が既に呼び出しているため、待機する必要があります。(ディブ!)
  3. ユーザー A が値を増やします (現在は 10)
  4. ユーザー B はまだ待機中です
  5. ユーザー A が値を保存します (レコードの値は 10)
  6. ユーザー B は値 (10) を読み取ることができるようになりました。
  7. ユーザー B が値を増やします (15)
  8. ユーザー B が値を保存する

これで、レコードの値は 15 になりました。これが、探している結果です。

過去に静的クラスを使用してこの問題を解決し、そのクラスのコンストラクター内で作成された静的オブジェクトにロックを設定して、すべての作業を 1 つの静的メソッドに集中させ、他の呼び出しを順番に待機させました。ただし、これはスケーラブルではありません。

また、トランザクションの最高の分離レベル (シリアル化可能) も、上記の不要な例のステップ 2 での読み取りを許可するため、うまくいかないと思います。

別の解決策は、独自のロックテーブルを作成してそこにロックを記録することだと思いますが、それは必要ではないようです。

私はこのプロジェクトを C# (3.5) と SQL サーバー 2008 で開発しています。

ハイブマインドは何を考えていますか?

4

1 に答える 1

0

多分私はこれ過小評価しているかもしれませんが、ロジックブロック全体をラップするだけではありません..

  • 読み取り値
  • 書き込み値

適切なレベルのデータベース トランザクションで?

SET TRANSACTION ISOLATION LEVEL
    { READ UNCOMMITTED
    | READ COMMITTED
    | REPEATABLE READ
    | SNAPSHOT
    | SERIALIZABLE
    }
[ ; ]
于 2009-04-01T08:04:24.710 に答える