2017-10-22 15 views
1

는 키가 이미 캐시에 존재하지 않는 경우 있는지 확인하는 가장 좋은 방법은 무엇이다 - 만드는 새로운 :Apache Ignite - Key가 이미 있는지 확인하는 방법?

cache.put("key3", 1); 

그렇지 않은 경우 내가 키가 이미 존재하는 경우 (1)에 의해 값을 증가 싶어 - 1로 설정하십시오.

+0

'cache.get()'함수를 사용하여 코드 앞에 값을 가져 와서 값이 있는지 확인하고 값이 증가했는지 확인할 수 있습니다. 초기 값을 설정하지 않은 경우 당신은 그것을하고 그 후에 당신의 성공을 논평 할 수 있습니까.감사합니다 – cramopy

+0

내가 값을 얻으려고하면 - 그것은 존재하지 않는 열쇠를 얻지 못하고 있습니다. '시도하기'또는 존재를 확인하는 방법이 가장 좋은 방법인가요? – Joe

+0

지금까지는 존재 여부를 확인하기위한 다른 방법을 찾지 못했기 때문에 try 메서드를 사용하려고합니다. – cramopy

답변

0

또한 키가 존재하는지 여부를 확인하기 위해 cache.containsKey(key)를 사용할 수 있습니다 여기에

은 증가 작업의 동시 안전한 구현입니다. cache.containsKey(key) 반환 부울 ​​값 (true/false)

0

의견에 명시된 바와 같이 값을 설정하기 전에 cache.get() 기능을 사용하십시오.

그런 다음 값을 저장하고 캐시에 다시 설정하기 전에 값을 늘리십시오.

값을 얻지 못하면 초기 값을 설정할 수 있습니다.

2

이전 값을 가져야하며, null인지 아닌지 확인하고, 값에 따라 1 또는 증가 된 이전 값을 캐시에 씁니다.

그러나 여러 프로세스 나 스레드가있는 경우이 키를 통해이 작업을 수행하려고하면 동시성 문제가 발생할 수 있습니다. 증분은 다음 세 단계로 구성된 복잡한 작업입니다.

  • 이전 값을 읽습니다.
  • 이전 값에 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; 
      } 
    ); 
} 
+0

'invoke()'가 사용되면 캐시를'TRANSACTIONAL '로 설정할 필요가 없습니다. '. EntryProcessor는 원 자성 모드에 상관없이 원자 적으로 호출되며 네트워크를 통해 전송되는 데이터의 양도 줄입니다. 성능 측면에서 볼 때 이러한 종류의 업데이트를 수행하는 가장 좋은 방법입니다. –

+0

@ValentinKulichenko 지적 해 주셔서 감사합니다! 제 생각에는 JavaDoc에서 invoke 메소드를 언급하는 것이 좋습니다. 나는 내 대답을 편집했다. – Denis

0

가장 간단한 방법은 getAndPutIfAbsent()을 사용하는 것 같습니다.

동시 트랜잭션에서 방금 작성된 오브젝트를 겹쳐 쓰지 않으려면 다른 메소드를 사용할 때 낙관적이고 비관적 인 트랜잭션이 오브젝트의 존재를 잠그는 방법에 대해 아직 명확하지 않습니다.