Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Redis 如何在事务中有选择地执行多个更新(而不是添加或更新)?_Redis_Stackexchange.redis - Fatal编程技术网

Redis 如何在事务中有选择地执行多个更新(而不是添加或更新)?

Redis 如何在事务中有选择地执行多个更新(而不是添加或更新)?,redis,stackexchange.redis,Redis,Stackexchange.redis,我有这个方法: public async Task<bool> UpdateIfExist<T>(string cacheKey, IDictionary<string, T> dictionary) { ITransaction tran = m_connection.GetDatabase().CreateTransaction(); List<HashEntry> hashEntries =

我有这个方法:

    public async Task<bool> UpdateIfExist<T>(string cacheKey, IDictionary<string, T> dictionary)
    {
        ITransaction tran = m_connection.GetDatabase().CreateTransaction();

        List<HashEntry> hashEntries = new List<HashEntry>();
        foreach (KeyValuePair<string, T> keyValuePair in dictionary)
        {
            tran.AddCondition(Condition.HashExists(cacheKey, keyValuePair.Key)); // <-- this guy is the problem

            HashEntry hashEntry = GetHashEntry(keyValuePair);
            hashEntries.Add(hashEntry);
        }

        bool committed = await tran.ExecuteAsync();
        if (committed)
        {
            await tran.HashSetAsync(cacheKey, hashEntries.ToArray()));
        }

        return committed;
    }
然后说,这是我的输入字典:

foo newBar
qoo qux
在我调用我的方法之后

应在缓存中:

实际值:



注意:如果Lua脚本是唯一的方法,我会尝试,但主要是寻找本机SE.Redis API方法。

没有本机Redis方法可以直接做到这一点,因此没有本机SE Redis方法可以直接做到这一点。这里我们真正想要的是一个
XX
修饰符(我的意思请参见
SET
),但在任何散列命令上都不存在,只有
NX
,这与您想要的相反(
NX
是“不存在时”)

如果没有Lua,您可以通过以下方式完成此操作:

  • 检查每个第一个的存在性
  • 修剪更新集
  • 创建仅包含修剪更新的事务,并附带断言检查的条件
但这需要大量的往返和操作,而且由于数据更改冲突,失败的可能性很高。因此,我要说的是,最好的方法是使用Lua(对于您希望成为原子的多个相关操作,通常情况下就是这样)。我会在
KEYS
中发送一个值,在
ARGV
中为每个条目发送一对值,并在Lua中循环,基本上(完全未测试-甚至可能不是有效语法)

对于i=1,#ARGV,2 do
如果redis.call('hexist',键[1],ARGV[i])==1则
redis.call('hset',键[1],ARGV[i],ARGV[i+1])
结束
结束

在尝试对单个键值对(不是集合)执行相同操作时,我刚刚了解到
等待GetDatabase().HashSetAsync(cacheKey、kvp.key、SerializeToJson(kvp.value),When.Exists)也不起作用。它抛出一个“Exists在此上下文中无效;允许的值为:Always,NotExists”。有趣。我想知道为什么Redis中缺少这么多这样的常见操作:(@nawfal你可以在Redis GitHub上提出它。逻辑命令应该是
HSETXX
foo newBar
qoo qux
myKey foo newBar // updated since the field exists in hash
      goo baz
myKey foo bar   // no change to cache
      goo baz