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”,然后以原子单元发送。如果您在执行之前“等待”,您将永远不会发送任何内容。只有调用 execute 之后才需要“等待”事务中的操作。

其次,您不能在事务期间查询数据。更具体地说,您可以,但只有在调用“执行”时才能得到结果。这是 redis 工作方式的基本部分:简单地说,redis 事务与 SQL 事务不同。这意味着您无法根据交易期间查询的数据做出决策。但是,您可以在事务之外查询数据,然后确保它不会更改。使用 bookleeve,事务上的 AddConstraint 方法可以添加许多可以在事务期间安全验证的常见断言。

第三,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 回答