2011-02-25 3 views
6

Redis 2.0.3다른 키의 카운터가 0 미만인 경우 원자 적으로 세트에서 항목을 제거 하시겠습니까?

내 Redis DB에 항목 집합이 있습니다. 각 항목에 연결된 카운터가 있습니다.

MULTI 
    SADD "items-set" "foo" 
    INCRBY "items:foo" 10000 
EXEC 

새 항목이 임의의 간격으로 세트에 추가됩니다.

사용자가 특정 동작을 수행 할 때, 카운터는 감소된다

카운터 대안 제로 (아래로 떨어질 때 I 원자 적 세트에서 항목을 삭제해야
new_counter = DECR "items:foo" 

: 카운터 정확히 0이되면, I 그에 대한 논리를 해결할 수 있습니다.)

if new_counter < 0 then 
    MULTI 
     SREM "items-set" "foo" 
     DEL "items:foo" 
    EXEC 
end 

어떻게 SETNX/GETSET와 항목 이름을 잠그지 않고이 작업을 수행 할 수 있습니까?

Redis에서 데이터를 저장하는 방식의 변경을 포함한 솔루션이 허용됩니다. (그러나, 단지의 경우, 내가 초기 텍스트에서 놓칠 수있는 몇 가지 작업 별 세부 사항을 대항 할 수있는 권리를 보유합니다.)

답변

10

그냥 레디 스 2.2의 새로운 시계 기능 사용

WATCH items-set items:foo 
count = GET items:foo 
IF count == 0: 
    MULTI 
    SREM items-set foo 
    SET items:foo count-1 
    EXEC 
ELSE: 
    MULTI 
    SET items:foo count-1 
    EXEC 

을 이 예를 이해하려면 시계 작동 방식을 이해해야합니다. 문서 http://redis.io에있는 문서를 확인하십시오.

p.s. Redis 2.0.3을 사용하여이를 수행 할 수있는 방법이 없습니다.

+0

아, 내 클라이언트 라이브러리 (sidereal) 지원 2.2 ... 아마도 다른 것으로 전환 할 때가되었습니다. –

+0

추가 명령을 조건부로 트리거해야하는 모든 작업에 대해 모든 클라이언트가 WATCH 및 MULTI/EXEC를 실행해야합니다. 가장 일반적인 경우는 가장 일반적인 경우에 오버 헤드가 발생합니다. Redis 2.6에서 Lua 스크립팅을 사용하면 이벤트에 대한 응답으로 스크립트 또는 스크립트 블록이 실행되는 영구적 인 WATCH를 등록 할 수 있습니까? 기본적으로 임의의 콜백 함수를 키 또는 키 집합에 대한 이벤트 리스너로 등록 할 수 있습니다. 그게 효율적일 수 있습니까? – MetaThis

2

루프에 있어야하므로 다른 사람이 중간에 값을 건드린 경우 다시 시도 할 수 있습니다.

success = false 
while not success 
    WATCH items-set items:foo 
    count = GET items:foo 
    MULTI 
    IF count == 0: 
     SREM items-set foo 
    SET items:foo count-1 
    success = EXEC