Redis C#-在事务中使用Incr值

问题描述

我正在尝试使用Redis INCR,并将增量值用作使用StackExchange.Redis从C#哈希生成的字段。 question这一点与我需要的要点相似,但是在Node中。

下面是我需要的东西。

            ITransaction transation = m_connection.GetDatabase()
                                                  .CreateTransaction();
            Task<long> incrementTask = transation.StringIncrementAsync(sequenceNumberRedisKey);


            if (await transation.ExecuteAsync())
            {
                long sequenceNumber = await incrementTask;
                await transation.HashSetAsync(responseRedisKey,sequenceNumber,response);
            }

请注意,sequenceNumber是我打算在交易中执行的第一项操作的结果。

代码似乎在我执行任何操作之前就执行并提交了事务。

  1. 这是在一次交易中执行多项操作的方法吗?
  2. 这样可以在操作2(HashSetAsync)中使用操作1(StringIncrementAsync)的结果吗?
  3. 如果HashSetAsync返回false,如何回滚序列号增量?
  4. 为什么没有显式提交?

解决方法

redis MULTI / EXEC单元有一个基本功能,这意味着您无法在操作过程中获得结果。因此,有两种常见的方式可以完成您所要求的操作:

  1. 使用Lua(ScriptEvaluate[Async]); Lua脚本在服务器上从头到尾执行,效率很高,并且避免了与往返时间(延迟或带宽)或与其他连接竞争的所有问题
  2. 使用乐观循环读取当前值,然后在SE-Redis中创建一个事务,该事务添加一个约束,使您刚读取的值相同,并在内部执行副作用交易;库将协调必要的WATCH等机制以使其稳健,但是如果约束条件证明无效(即库返回false),则需要从头开始重做所有内容

坦白说,这些天我总是会引导人们选择方案1。如果服务器端Lua脚本不可用,则选项2仅“吸引人”(并且我非常错误地使用了该术语)。

我不在PC上,但是我猜脚本看起来像这样:

local id = redis.call("incr",KEYS[1])
redis.call("hset",KEYS[2],tostring(id),ARGV[1])
return id

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...