Redis C# - Using Incr value in a transaction

不羁岁月 提交于 2020-12-13 04:40:03

问题


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.

The below is something like I need.

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

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. Is this the way to do multiple operations in one transaction?
  2. Is this the way I could use the result of operation 1 (StringIncrementAsync) in operation 2 (HashSetAsync) ?
  3. How do I rollback the sequence number increment if HashSetAsync returns false?
  4. Why is there no explicit commit?

回答1:


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. 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

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


来源:https://stackoverflow.com/questions/63945465/redis-c-sharp-using-incr-value-in-a-transaction

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!