14

Web サービスでデータベースを編集する関数がある場合、同じ行を編集しようとすると、一度に 1 つのスレッドのみを実行する必要があります。

void EditCheck(long checkid)
    {

        if (isCheckCosed)
            throw new Exception("check is already closed");

        //do stuff

        //after i edit my check i want to close it.
        CloseCheck();
    }

関数全体をロックできることはわかっていますが、異なるスレッドが同じチェックを編集しようとすることはほとんどないため、パフォーマンスが低下します。

同じチェックIDを持つ他のスレッドのみをロックアウトする方法はありますか?

アップデート

私は使用OleDbConnectionし、MySqlConnection

OleDbCommand oleDbCommand = AccessTrans != null ?
new OleDbCommand(sql, AccessConn, AccessTrans) : new OleDbCommand(sql, AccessConn); 
oleDbCommand.ExecuteNonQuery();

のための同じ機能MySqlCommand

そして、通常のINSERTおよびUPDATE sqlコマンドを使用します。およびトランザクションが存在するかどうかがチェックされます。したがって、この関数は、トランザクションが必要な場合、または上位レベルの関数ではない場合に機能します。

データベースから読み取るために、私が記入しますDataTable

OleDbCommand oleDbCommand = AccessTrans != null ? new OleDbCommand(sql, AccessConn, AccessTrans) : new OleDbCommand(sql, AccessConn);
OleDbDataAdapter dAdapter = new OleDbDataAdapter();
dAdapter.SelectCommand = oleDbCommand;
dAdapter.Fill(dTable);
return dTable;
4

2 に答える 2

25

a を使用して、ConcurrentDictionaryロックできるオブジェクトに各 ID をマップできます。

public class Foo
{
    private ConcurrentDictionary<long, object> dictionary = 
        new ConcurrentDictionary<long, object>();

    private void EditCheck(long checkid)
    {
        var key = dictionary.GetOrAdd(checkid, new object());
        lock (key)
        {
            //Do stuff with key
        }
    }
}
于 2013-09-25T15:26:52.907 に答える
0

パフォーマンスを向上させたい場合は、できるだけ最近の時点でロックする必要があります。データベースを使用しているため、DB ロックを使用できます。次の 2 つのオプションがあります。

  1. を使用して、 SQL の選択と更新Select for updateの適切な方法を見てください
  2. それを行うための私見の最良のアプローチである楽観的ロックを使用してくださいch05.html

どちらのアプローチでも、プログラムによるものよりも多くの DB リソースを使用できることに注意してください。これは、提案された辞書よりも優れています。なぜですか?

データを複製すると、DB 内のデータがランタイム ディクショナリに複製され、それらを同期する必要があるため、誰かがデータベースを更新して新しいものを追加したid場合は、すぐに辞書を更新する必要があります。

確かに、小規模な保守 (例: リポジトリ) クラスでは実行可能ですが、プロジェクトが大きくなると、同僚の何人かがこの情報を忘れて、そのような種類のバグを見つけ始める可能性があります。

于 2013-09-26T06:29:56.263 に答える