在事务中使用incr值

cld4siwp  于 2021-06-08  发布在  Redis
关注(0)|答案(1)|浏览(401)

我尝试使用redis incr和递增的值作为c#使用stackexchange.redis的散列中的字段。这个问题与我所需要的问题相似,但在节点中。
下面是我需要的东西。

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 是我打算在事务中执行的第一个操作的结果。
代码看起来好像在我执行任何操作之前就执行并提交了事务。
这是在一个事务中执行多个操作的方法吗?
这是我在操作2(hashsetasync)中使用操作1(stringincrementasync)的结果的方法吗?
如果hashsetasync返回false,如何回滚序列号增量?
为什么没有明确的承诺?

drkbr07n

drkbr07n1#

redis multi/exec单元有一个基本特性,即在操作过程中无法获得结果。因此,有两种常见的方法来满足您的要求:
使用lua( ScriptEvaluate[Async] ); lua脚本从头到尾在服务器上执行,效率很高,并且避免了与往返时间(延迟或带宽)或来自其他连接的竞争相关的所有问题
使用一个乐观循环读取当前值,然后在seredis中创建一个事务,该事务添加一个约束,即刚才读取的值是相同的,并在事务中执行副作用;库将协调必要的watch etc机械以使其健壮,但如果约束条件被证明无效(即库返回 false ),你需要从头开始重做
坦率地说,这些天我总是引导人们选择1;如果服务器端lua脚本不可用,那么选项2只是“吸引人的”(我使用这个术语是非常错误的)。
我不在电脑前,但我猜脚本应该是这样的:

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

相关问题