【问题标题】:StackExchange.Redis Transaction chaining parametersStackExchange.Redis 事务链接参数
【发布时间】:2021-05-30 11:08:21
【问题描述】:

我正在尝试执行包含两个操作的基本事务操作

  1. 获取集合的长度scard MySet
  2. 弹出给定长度的整个集合:spop MySet len

我知道可以连续使用smembersdel。但我想要实现的是获取第一个操作的输出并在第二个操作中使用它并在事务中执行。到目前为止,这是我尝试过的:

var transaction = this.cacheClient.Db1.Database.CreateTransaction();
var itemLength = transaction.SetLengthAsync(key).ContinueWith(async lengthTask =>
{
  var length = await lengthTask;
  try
  {
       // here I want to pass the length argument
       return await transaction.SetPopAsync(key, length); // probably here transaction is already committed
      // so it never passes this line and no exceptions thrown.
  }
  catch (Exception ex)
  {
       throw;
  }

});

await transaction.ExecuteAsync();

另外,我用CreateBatch 尝试了同样的事情并得到了同样的结果。我目前正在使用上面提到的解决方法。我知道也可以评估 Lua 脚本,但我想知道事务是否可能,或者我做错了什么。

【问题讨论】:

    标签: c# redis stackexchange.redis


    【解决方案1】:

    redis 的本质是您无法在 multi/exec 期间读取数据 - 您只能在 exec 运行时获得结果,这意味着无法在 内部使用这些结果 多重。您正在尝试的事情注定要失败。有两种方法可以在这里做你想做的事:

    1. 推测性地读取您需要的内容,然后使用该知识作为 约束 执行一个 multi/exec(事务)块,SE.Redis 将在 WATCH 块内强制执行;老实说,这真的很复杂,很难做到正确
    2. 使用 Lua,意思是:ScriptEvaluate[Async],您可以在其中执行一系列操作,在服务器上连续执行而不与其他连接竞争

    选项 2 几乎总是正确的方法,自从它成为可能以来。

    【讨论】:

    • 谢谢,我怀疑做了一些不自然的事情,现在已经澄清了。
    • 这也称为乐观锁机制。
    猜你喜欢
    • 1970-01-01
    • 2014-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-06
    相关资源
    最近更新 更多