2013-08-26 6 views
3

Redis를 사용하여 일련의 명령을 수행하고 싶습니다. 즉, 시퀀스가 ​​실행되는 동안 다른 클라이언트가 데이터베이스에서 변경을 수행하지 않도록해야합니다.읽기 작업의 Redis에서의 트랜잭션

은 내가 자성 사용하여 트랜잭션을 보장하기 위해 MULTIEXEC 문을 사용할 수 명령을 쓰기를 사용합니다. 그러나, 명령을 내 트랜잭션에서 사용하고 싶습니다. 따라서 읽기 명령도 대기 중이므로 MULTI을 사용할 수 없습니다!

은 기본적으로 원자 방식으로, 나는 다음을 수행해야합니다 데이터베이스에서

  1. 읽기 x,
  2. , x을 바탕으로 저장 f(x)를 데이터베이스에.

1. 및 2.는 둘 다 단일 트랜잭션이어야합니다.

어떻게 할 수 있습니까?

+0

Lua 스크립팅을 사용해 볼 수 있습니다. http://redis.io/commands/eval –

답변

9

두 가지 좋은 해결책이 있습니다.

옵션 1 :

당신은 당신이에서 읽고있는 키에 WATCH를 발행 할 필요가있다. 귀하의 트랜잭션이 같은 것을 보일 것이다 :이 예에서는

WATCH x 
x = GET x 
MULTI 
SET y, f(x) 
EXEC 

을, 멀티 블록 내부의 쓰기 명령은 원자 적으로 실행됩니다 만, WATCH가 호출 된 이후 키 x의 값이 변경되지 않은 경우에만. 이를 낙관적 잠금이라고합니다. x의 값이 변경되면 응용 프로그램에 오류가 발생하고 다음에 수행 할 작업을 결정해야합니다. 새로운 값인 x을 사용하여 다시 시도 할 가능성이 있습니다.

옵션 2 :

레디 스 지금 루아 스크립트를 지원하며, 루아 스크립트를 원자 적으로 실행됩니다. 논리를 루아 스크립트로 캡슐화 할 수 있다면 키를 읽고 f(x) 로직을 실행하고 그 결과를 모두 원자 적으로 저장할 수 있습니다. 이것은 수행하는 논리에 따라 까다로울 수도 있고 옵션이 아닐 수도 있습니다. redis를 실행시키고 자하는 스크립트에 직접 하드 코딩함으로써 lua에 패스 값과 같은 추악한 해킹을해야 할 수도 있습니다. 즉, 작동 시키면이 방법이 안정적이고 실행 가능해야하며, EXEC 오류를 처리 할 필요가 없습니다.

+0

옵션 1은 작업의 반복적 인 재 시도가 합리적인 해결책으로 보이는 내 요구 사항에 완벽합니다. 현재, 필자의 애플리케이션 로직은 필자가 제공 한 예제와 비교할 때 훨씬 더 복잡하지만 아직 Lua를 살펴볼 예정이다. 고마워요! – Tregoreg

관련 문제