【发布时间】:2021-07-12 15:53:00
【问题描述】:
我需要生成一个计数器,该计数器将发送到一些 api 调用。我的应用程序在多个节点上运行,所以我想如何生成唯一计数器。 我试过下面的代码
public static long GetTransactionCountForUser(int telcoId)
{
long valreturn = 0;
string key = "TelcoId:" + telcoId + ":Sequence";
if (Muxer != null && Muxer.IsConnected && (Muxer.GetDatabase()) != null)
{
IDatabase db = Muxer.GetDatabase();
var val = db.StringGet(key);
int maxVal = 999;
if (Convert.ToInt32(val) < maxVal)
{
valreturn = db.StringIncrement(key);
}
else
{
bool isdone = db.StringSet(key, valreturn);
//db.SetAdd(key,new RedisValue) .StringIncrement(key, Convert.ToDouble(val))
}
}
return valreturn;
}
并通过 Task Parallel 库对其进行运行测试。当我有边界值时,我看到的是设置了多次 0 条目
请让我知道我需要做什么更正
更新: 我的最终逻辑如下
public static long GetSequenceNumberForTelcoApiCallViaLuaScript(int telcoId)
{
long valreturn = 0;
long maxIncrement = 9999;//todo via configuration
if (true)//todo via configuration
{
IDatabase db;
string key = "TelcoId:" + telcoId + ":SequenceNumber";
if (Muxer != null && Muxer.IsConnected && (db = Muxer.GetDatabase()) != null)
{
valreturn = (long)db.ScriptEvaluate(@"
local result = redis.call('incr', KEYS[1])
if result > tonumber(ARGV[1]) then
result = 1
redis.call('set', KEYS[1], result)
end
return result", new RedisKey[] { key }, flags: CommandFlags.HighPriority, values: new RedisValue[] { maxIncrement });
}
}
return valreturn;
}
【问题讨论】:
-
你为什么不使用一个只有一个标识列的简单表,做一个插入并使用返回的 SCOPE_IDENTITY() - 这应该总是返回一些唯一的东西。
-
我想避免分贝插入/分贝往返。我支持通过 Redis 进行缓存,我想完全实现这一点
-
@KamranShahid 请不要使用
string.Format来参数化它;我将编辑我的示例以显示首选方式 -
顺便说一句;我可能错了,但我认为
GetDatabase永远不会返回0,因此检查可能是多余的 -
已使用参数值用法更新了我的答案。所以你认为没有Muxer连接但没有数据库的情况?
标签: c# redis .net-4.5 stackexchange.redis servicestack.redis