c# - Redis C# - 在事务中使用 Incr 值
问题描述
我正在尝试使用 Redis INCR 并将增量值用作 C# 中使用 StackExchange.Redis 的哈希中的字段。这个问题与我需要的类似,但在 Node.js 中。
下面是我需要的东西。
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,如何回滚序列号增量?
- 为什么没有明确的提交?
解决方案
redis MULTI/EXEC 单元有一个基本特性,这意味着您在操作期间无法获得结果。因此,有两种常见的方法可以满足您的要求:
- 使用 Lua (
ScriptEvaluate[Async]
); Lua 脚本在服务器上从头到尾执行,高效,并避免与往返时间(延迟或带宽)或来自其他连接的竞争相关的所有问题 - 使用一个读取当前值的乐观循环,然后在 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
推荐阅读
- z3 - 为什么 z3 horn 求解器结果未知,为什么这是未知原因
- sql - 如何在sql中编写此连接条件?
- react-native - react-native - 模态总是可见的
- ios - Swift KVO 持有对象引用计数
- c# - Xamarin Forms 在应用程序进入后台时运行代码(即进入睡眠)
- git - 为什么 Tortoise GIT 在提交期间将状态显示为版本化文件的重命名
- mongodb - 将 ReactiveMongoTemplate 与 Kotlin 协程一起使用
- javascript - 如何使用 React Redux 插入带有帖子的数据?
- java - 尝试在 Java 中将 String 值转换为 Double 时出现异常
- go - 如何等待回调函数返回?