StackExchange.Redis Transaction

时间:2015-10-08 06:54:10

标签: c# asynchronous stackexchange.redis

如何在一个事务中运行两个异步方法? 例如:

  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);

也许有人知道如何从列表中获取范围并在事务中删除此范围后?

1 个答案:

答案 0 :(得分:1)

你不能这样做。

解决方案是为读取操作创建常规IDatabase,为写操作创建ITransaction

为什么......?因为 StackExchange.Redis 事务是Redis'MULTI / EXEC命令的抽象。也就是说,事务是批量发送到Redis的命令队列,它们的执行是原子的。一旦您拨打ITransaction.Execute,就会完成整个批量发送部分。

这是无法在Redis事务中执行读取操作的原因。命令排队并批量执行,因此,一旦bacthing结束,你就可以继续使用,这不会成为包装事务的一部分......

OP在一些评论中说...

  

也许你可以给我一些建议吗?因为我需要得到物品   从列表中删除此项目后。而这些操作必须是   线程安全的。

线程安全与Redis事务完全无关。负责将一些锁定方法作为应用程序层的一部分来实施的是您。好吧,您可以使用Redis将 lock 实现为进程间多线程锁定标志存储。 Read about this on this article from official Redis site.

事实上,请查看其他问答:StackExchange.Redis - LockTake / LockRelease Usage