2012-06-11 2 views
3

python 패키지 (redis-py)를 사용하여 redis 데이터베이스를 조작하고 있습니다. 나는 redis에서 해쉬의 키와 값을 설정하는 클라이언트가있다. 해시가 존재할 때만 키와 값을 설정하기를 원합니다. 해시가 존재하지 않으면 키와 값을 설정하면 해시가 작성됩니다. 이는 원하지 않는 해시입니다.Redis, 기존 키에 대해서만 조작 허용

redis-py 페이지 (https://github.com/andymccurdy/redis-py)에서 저자는 클라이언트 측에서 원자 적 조작을 수행하는 방법을 제안했습니다. 그래서 비슷한 기능을 썼습니다 :

with r.pipeline() as pipe: 
     while True: 
      try: 
       pipe.watch("a_hash") 
       if pipe.exists("a_hash"): 
        pipe.hset("a_hash", "key", "value")     
       break 
      except redis.WatchError: 
       continue 
      finally: 
       pipe.reset() 

그러나 이것은 효과가없는 것처럼 보입니다. 다른 클라이언트에서 해시를 삭제 한 후에도이 코드는이 해시로 만들어 지므로이 코드는 원자 적 연산이 아닙니다. 누군가이 코드의 문제점을 파악하는 데 도움을 줄 수 있습니까? 아니면이 목적을 달성하는 것이 더 낫습니까?

감사합니다.

답변

4

Redis documentation에서 설명한대로 WATCH/MULTI/EXEC 블록의 정의를 읽는 것이 좋습니다.

이러한 블록에서는 MULTI와 EXEC 사이의 명령 만 실제로 원자 적으로 처리됩니다 (조건부로는 시계에 따라 전부 또는 일부 의미가 있음).

예에서 EXISTS 및 HSET 명령은 원자 적으로 실행되지 않습니다. 실제로, 당신은이 원 자성을 필요로하지 않습니다 : 당신이 원하는 것은 조건부 실행입니다.

이 잘 작동해야 다음이 존재 후 키가 삭제되지만 MULTI 전에 HSET이 시계 덕분에 실행되지 않습니다

with r.pipeline() as pipe: 
    while True: 
     try: 
      pipe.watch("a_hash") 
      if pipe.exists("a_hash"): 
       pipe.multi() 
       pipe.hset("a_hash", "key", "value") 
       pipe.execute() 
      break 
     except redis.WatchError: 
      continue 
     finally: 
      pipe.reset() 

합니다.

Redis 2.6에서는 Lua server-side script이 쓰기 쉽고 효율적입니다.

+0

감사합니다. Didier. 한 번 더 질문입니다, 멀티가 삭제 된 후에 키가 삭제되면 어떻게 될까요? redis는 멀티 이후에 명령을 대기 행렬에 넣기 때문에이 상황에서 여전히 실행됩니다. – qkhhly

+0

키가 MULTI와 HSET 사이 또는 HSET과 EXEC 사이에서 삭제 된 경우 MULTI/EXEC 블록이 중단되고 HSET가 적용되지 않습니다. –

+0

이 예제에서 reset()이 필요합니까? 문서에서 "파이프 라인이 컨텍스트 관리자로 사용되면 reset()이 자동으로 호출됩니다." –

관련 문제