StackExchange.Redis 交易

StackExchange.Redis Transaction

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

例如:

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

也许有人知道如何从列表中获取一个范围,然后在事务中删除这个范围?

你不能这样做。

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

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

后完成

这就是无法在 Redis 事务中执行读取操作的原因。命令按批次排队和执行,因此,您可以 继续 一旦 bacting 结束,这不会作为包装事务的一部分...

OP 在一些评论中说...

Maybe you can something suggest for me? Because I need to get items from list and after delete this items. And these operations must be thread-safe.

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

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