如何在一个事务中运行两个异步方法? 例如:
var batchIds = new ConcurrentBag<int>();
var trans = redis.CreateTransaction();
var task = trans.ListRangeAsync(AllItems, 0L, batchSize - 1).ContinueWith(t =>
{
t?.Result.ToList().ForEach(x => batchIds.Add(JsonConvert.DeserializeObject<StockItemDto>(x).Id));
}).ContinueWith(t=>{ trans.ListTrimAsync(AllItems, batchSize, -1); }); // This not work
// This work but I'm not sure if taskRemove run exaclly after task
var taskRemove = trans.ListTrimAsync(AllItems, batchSize, -1);
trans.Execute(CommandFlags.FireAndForget);
Task.WaitAll(task, taskRemove);
也许有人知道如何从列表中获取范围并在事务中删除此范围后?
答案 0 :(得分:1)
你不能这样做。
解决方案是为读取操作创建常规IDatabase
,为写操作创建ITransaction
。
为什么......?因为 StackExchange.Redis 事务是Redis'MULTI
/ EXEC
命令的抽象。也就是说,事务是批量发送到Redis的命令队列,它们的执行是原子的。一旦您拨打ITransaction.Execute
,就会完成整个批量发送部分。
这是无法在Redis事务中执行读取操作的原因。命令排队并批量执行,因此,一旦bacthing结束,你就可以继续使用,这不会成为包装事务的一部分......
也许你可以给我一些建议吗?因为我需要得到物品 从列表中删除此项目后。而这些操作必须是 线程安全的。
线程安全与Redis事务完全无关。负责将一些锁定方法作为应用程序层的一部分来实施的是您。好吧,您可以使用Redis将 lock 实现为进程间或多线程锁定标志存储。 Read about this on this article from official Redis site.
事实上,请查看其他问答:StackExchange.Redis - LockTake / LockRelease Usage