Redis C# - 在事务中使用 Incr 值 [英] Redis C# - Using Incr value in a transaction

查看:141
本文介绍了Redis C# - 在事务中使用 Incr 值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Redis INCR 和使用 StackExchange.Redis 的 C# 中用作哈希字段的递增值.这个问题点与我需要的类似,但在Node中.

I'm trying use Redis INCR and the incremented value to be used as a field in a Hash from C# using StackExchange.Redis. This question points similar to what I need, but in 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 是我打算在事务中执行的第一个操作的结果.

Note that sequenceNumber is the result of the first operation I intend to do in the transaction.

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

The code seems like the transaction executes and commits before I even do any of my operations.

  1. 这是在一个事务中进行多项操作的方式吗?
  2. 这是我可以在操作 2 (HashSetAsync) 中使用操作 1 (StringIncrementAsync) 的结果的方式吗?
  3. 如果 HashSetAsync 返回 false,我如何回滚序列号增量?
  4. 为什么没有明确的提交?

推荐答案

redis MULTI/EXEC 单元有一个基本特性,这意味着您在操作过程中无法获得结果.因此,有两种常见的方法可以满足您的要求:

There is a fundamental feature of redis MULTI/EXEC units that means you cannot get results during the operation. As such, there are two common ways of doing what you ask:

  1. 使用 Lua (ScriptEvaluate[Async]);Lua 脚本在服务器上自始至终执行,效率高,并且避免了与往返时间(延迟或带宽)或来自其他连接的竞争相关的所有问题
  2. 使用乐观循环读取当前值,然后在 SE-Redis 中创建一个事务,添加一个约束,即您刚刚读取的值是相同的,并执行内部的副作用交易;库将协调必要的 WATCH 等机制以使其稳健,但如果约束条件无效(即库返回 false),您需要从头开始重做所有事情
  1. Use Lua (ScriptEvaluate[Async]); a Lua script executes on the server start-to-end, is efficient, and avoids all problems associated with round-trip time (latency or bandwidth) or competition from other connections
  2. Use an optimistic loop that reads the current value, then creates a transaction in SE-Redis that adds a constraint that the value you just read is the same, and execute the side-effects inside the transaction; the library will co-ordinate the necessary WATCH etc machinery to make this robust, but if the constraint condition turns out to be invalid (i.e. the library returns false), you need to redo everything from the start

坦率地说,这些天我总是引导人们选择选项 1;选项 2 只是有吸引力的"(而且我使用该术语非常不正确)如果服务器端 Lua 脚本不可用.

Frankly, these days I would always guide people to option 1; option 2 is only "appealing" (and I use that term quite incorrectly) if server-side Lua scripting is not available.

我不在电脑前,但我猜脚本应该是这样的:

I'm not at a PC, but I'm guessing the script would look something like:

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

这篇关于Redis C# - 在事务中使用 Incr 值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆