下面的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
}
Run Code Online (Sandbox Code Playgroud)
但是当我尝试将它们包装在一个事务中时它就会停止工作.不抛出异常,但如果我调试执行似乎停止在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
}
Run Code Online (Sandbox Code Playgroud)
事务在本地缓冲,直到您调用"exec",然后以原子单位发送.如果你在执行前"等待",你将永远不会发送任何东西.只有在调用execute 之后才有必要"等待"事务中的操作.
其次,您无法在事务期间查询数据.更具体地说,您可以,但只有在调用"执行"时才能获得结果.这是redis工作原理的基本部分:简单地说,redis事务与SQL事务不同.这意味着您无法根据转换期间查询的数据做出决策.但是,您可以查询事务外部的数据,然后确保它不会更改.使用booksleeve,事务上的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
}
Run Code Online (Sandbox Code Playgroud)
我可以添加一个GetAllString,如果它使上述更容易.