0

DB オブジェクトにロードされる一連の DB エンティティがあります。同じ DB エンティティが複数の DB オブジェクトにロードされる場合があります。定期的に、DB エンティティには特別な処理が必要になります。この処理は、一度に 1 つのスレッドで実行する必要があります。ここでロックがかかります。

編集: 重要な注意: プロセスは低速の Web サービスを呼び出します。これは、同時実行を防止しようとしているものです。ロックなしでこれを安全に行う方法がわかりません。

そこで、DB オブジェクトがロックのために参照する「南京錠」オブジェクトを作成します。南京錠オブジェクトはエンティティ ベースであるため、同じエンティティの 2 つ以上の DB オブジェクトが同じ南京錠オブジェクトを使用します。DB エンティティの ID をキーとして使用して、これらの南京錠をディクショナリ オブジェクトに格納しています。南京錠オブジェクトも単純な文字列オブジェクトです。これは正しいアプローチですか?私は、これをエンジニアリングまたは単純化していると考えています。アプローチが正しければ、このコードはどのように見えるでしょうか? 動作しますが、まだ負荷をかけた状態でテストしていません。

ありがとう :)

public static func(CustomObject o)
{
    if (ReadyForUpdate(o))
    {
        lock (LookupPadLockByID(object.ID)
        {
            if (ReadyForUpdate(o))
            {
                PerformUpdate(object);
            }
        }
    }
}

private static readonly object padlockLock = new object();
private static readonly Dictionary<int, string> padLocks = new Dictionary<int,string>();
private static object LookupPadLockByID(int uniqueID)
{
    lock (padlockLock)
    {
        if (!padLocks.ContainsKey(uniqueID))
        {
            padLocks.Add(uniqueID, uniqueID + " is locked");
        }
    }

    return padLocks[uniqueID];
}
4

4 に答える 4

1

まあ、文字列をロックしてしまうことになりますが、これは良い考えではありません (ただし、連結はインターンが大きな問題にならないことを意味します)。より大きな問題は次のとおりです。

  • ロックを解除していないようですpadLocks- それは問題ですか?
  • の外部で辞書にアクセスしますpadlockLock。のreturn中にある必要がありますlock

この秒では、これはより簡単になります。

object itemLock;
if (!padLocks.TryGetValue(uniqueID, out itemLock)) {
    itemLock = new object();
    padLocks.Add(uniqueID, itemLock);
}
return itemLock;

このコードがかなりローカルな場合 (つまり、オブジェクトがまだエスケープされていない場合)、単にlockレコード自体を削除するだけでよいでしょうか? はるかに単純...

于 2009-01-13T21:59:18.817 に答える
1

文字列をロックすることはお勧めできません。2 つの選択肢を提案します。

  1. Dictionary<int,object>padLocks のタイプとして a を使用new object();し、値として a を入力します。
  2. 単に ID を保持するクラスを作成します。デバッグ中に LockPad クラスを見たい場合は、これが読みやすくなります。

ロックパッド クラス:

class LockPad {
    public int Id { get; private set; }

    public LockPad(int id) {
        this.Id = id;
    }

    public override string ToString() {
        return "lock of " + id.ToString();
    }
}

次に、そのクラスをロックします。

于 2009-01-13T23:41:21.107 に答える
0

私はあなたがエンジニアリングを超えていると思います。DBエンティティのみを保護する必要がある場合(コードでは「オブジェクト」で表されていると想定していますが、これを「エンティティ」に変更します)、それをロックとして使用できます。任意の参照オブジェクトをロックとして使用できます。

public static func(CustomObject o)
{
    if (ReadyForUpdate(o))
    {
        lock (entity)
        {
                if (ReadyForUpdate(o))
                {
                        PerformUpdate(entity);
                }
        }
    }
}
于 2009-01-13T22:05:00.893 に答える
0

任意のタイプの標準データベースを使用している場合は、トランザクションとテーブル/行ロックを優先して、これらのクライアント側ロックを完全にダンプすることをお勧めします。

于 2009-01-13T22:10:06.517 に答える