3

以下の 3 つのコマンドは、そのまま実行すると完全に機能します。

using (var redis = NewRedisConnection)
{
    await redis.Open();
    var allKeys = await redis.Keys.Find(db, "searchPattern");
    var allVals = await redis.Strings.GetString(db, allKeys);
    await redis.Keys.Remove(db, allKeys);

    //process the data I pull from redis
}

しかし、それらをトランザクションでラップしようとすると、機能しなくなります。例外はスローされませんが、デバッグするとvar allKeys = ...、トランザクションのセットアップ中に実行が停止するように見えますか?

using (var redis = NewRedisConnection)
{
    await redis.Open();
    var tran = redis.Createtransaction();

    var allKeys = await tran.Keys.Find(db, "searchPattern");
    var allVals = await tran.Strings.GetString(db, allKeys);
    await tran.Keys.Remove(db, allKeys);

    await tran.Execute();
    //process the data I pull from redis
}
4

1 に答える 1

6

トランザクションは、「exec」を呼び出すまでローカルにバッファリングされ、その後アトミック単位で送信されます。exec の前に「待機」すると、何も送信されません。execute が呼び出された後にのみ、トランザクション内の操作を「待機」する必要があります。

次に、トランザクション中にデータを照会することはできません。より具体的には、実行できますが、「実行」を呼び出したときにのみ結果が得られます。これは、redis の動作の基本的な部分です。単純に、redis トランザクションは SQL トランザクションと同じではありません。つまり、トランザクション中に照会されたデータに基づいて決定を下すことはできません。ただし、トランザクションの外部でデータをクエリして、変更されないようにすることはできます。Booksleeve では、トランザクションの AddConstraint メソッドは、トランザクション中に安全に検証できる多くの一般的なアサーションを追加できます。

第 3 に、Keys.Findはルーチン コードの一部として使用しないでください。これは通常、デバッグやデータベース分析中に使用することはほとんどありません。

あなたの場合、「ハッシュ」がより良いオプションになるかどうか疑問に思います-したがって、「このパターンに一致するすべてのキーを見つけ、それらのキーからすべての値を取得し、それらのすべてのキーを削除する」のではなく、「すべての値を取得する」として実行できますこのハッシュから、このハッシュを削除します。」

のようなもの (注: 携帯電話のコード! 入力ミスを許してください)

using(var tran = conn.CreateTransaction())
{
    valsPending = tran.Hashes.GetAll(db, key);
    tran.Keys.Remove(db, key);
    await tran.Execute();
    var vals = await valsPending;
    // iterate dictionary in "vals", decoding each .Value with UTF-8
}

上記が簡単になる場合は、GetAllString を追加できます。

于 2012-11-17T23:26:38.493 に答える