检查Key是否已存在于缓存中的最佳方法是什么,如果不存在 - 创建一个新的方法:
cache.put("key3", 1);
如果密钥已经存在,我希望将值增加1,如果密钥不存在,则将其设置为1.
答案 0 :(得分:3)
你应该得到一个旧的值,看看它是否为null,并且根据它,要么写1或增加旧的值来缓存。
但是如果您有多个进程或线程,尝试在同一个键上执行此操作,则可能会遇到并发问题。增量是一项复杂的操作,包括三个步骤:
如果同时执行这些操作,则其中一些可能会丢失。您需要使这三个操作以原子方式执行。
有几种选择可以实现它。其中之一是创建缓存transactional并在事务中执行所需的操作,或者在缓存条目上保持显式锁定。这是通过在缓存配置中指定TRANSACTIONAL原子模式来实现的。使用CacheConfiguration.setAtomicityMode(...)执行此操作。要获取锁定,请使用IgniteCache.lock(...)方法。可以致电Ignite.transactions()。txStart(...)
开始交易有关性能的最佳选择是使用IgniteCache.invoke(...)。调用操作是以原子方式执行的,无论缓存原子性如何,因此即使在原子缓存上也可以安全地调用它。
这是增量操作的并发安全实现:
int inc(IgniteCache<String, Integer> cache, String key) {
return cache.invoke(key, (entry, arg) -> {
Integer oldValue = entry.getValue();
Integer newValue;
if (oldValue == null)
newValue = 1;
else
newValue = oldValue + 1;
entry.setValue(newValue);
return newValue;
}
);
}
答案 1 :(得分:0)
如评论中所述,请在设置值之前使用cache.get()
功能。
然后只需存储该值并将其增加,然后再将其设置回缓存。
如果获取值失败,您可以设置初始值。
答案 2 :(得分:0)
您还可以使用cache.containsKey(key)
检查密钥是否存在。
cache.containsKey(key)
返回布尔值(true / false)
答案 3 :(得分:0)
最简单的方法似乎是使用getAndPutIfAbsent()
。
为了防止覆盖刚刚在并发事务中创建的对象,我仍然有点不清楚乐观和悲观事务如何在使用其他方法时锁定对象的不存在。