복붙노트

[REDIS] 레디 스 거래 및 시계 문

REDIS

레디 스 거래 및 시계 문

당신은 "작은 레디 스 북"에서 다음 예제 설명해 주 시겠어요 :

redis.multi() 
current = redis.get('powerlevel') 
redis.set('powerlevel', current + 1) 
redis.exec()
redis.watch('powerlevel') 
current = redis.get('powerlevel') 
redis.multi() 
redis.set('powerlevel', current + 1) 
redis.exec()

우리는 트랜잭션에 증가 실행할 수 없습니다 왜 다른 명령에 의해 중단 될 수없는? 우리는 대신 반복 할 필요 아무도 트랜잭션이 시작되기 전에 값을 변경하지 않을 때까지 기다릴 이유는 무엇입니까?

해결법

  1. ==============================

    1.몇 가지 질문이 여기에있다.

    몇 가지 질문이 여기에있다.

    우리는 트랜잭션에 증가 실행할 수없는 이유는 1) 다른 명령에 의해 중단 될 수없는?

    레디 스 "거래"대부분의 사람들이 트랜잭션이 고전 DBMS에서 생각하는 것보다 완전히 다른 것을 먼저 유의하시기 바랍니다.

    # Does not work
    redis.multi() 
    current = redis.get('powerlevel') 
    redis.set('powerlevel', current + 1) 
    redis.exec()
    

    당신은 (레디 스에서) 서버 측에서 실행되며, 무엇을하는 것은 (스크립트에서) 클라이언트 측에서 실행되는 것을 이해할 필요가있다. 위의 코드에서 GET 및 SET 명령은 현재 1 + 전류의 계산에 레디 스 측 있지만 할당에 실행됩니다은 클라이언트 측에서 실행되도록되어있다.

    보증 자성하려면 MULTI / EXEC 블록은 간부까지 레디 스 명령의 실행을 지연. 따라서 클라이언트는 메모리에 GET 및 SET 명령을 쌓아, 그리고 한 번에와 원자 결국이를 실행합니다. 물론, GET과 점진의 결과에 할당 현재의 시도는 이전에 잘 발생합니다. 실제로 redis.get 방법은 문자열 "QUEUED는"명령이 지연 신호를 반환하고, 점진하지 않습니다 작동합니다.

    MULTI / EXEC 블록에서 당신은 단지 그 매개 변수 완전히 블록의 시작 전에 알 수있다 명령을 사용할 수 있습니다. 당신은 자세한 내용은 설명서를 참조 할 수 있습니다.

    2) 왜 우리는 대신 반복 할 필요 아무도 트랜잭션이 시작되기 전에 값을 변경하지 않을 때까지 기다릴?

    이 동시 낙관적 인 패턴의 예입니다.

    우리는 어떤 시계 / MULTI / EXEC를 사용하지 않는 경우에, 우리는 잠재적 인 경쟁 조건이있을 것입니다 :

    # Initial arbitrary value
    powerlevel = 10
    session A: GET powerlevel -> 10
    session B: GET powerlevel -> 10
    session A: current = 10 + 1
    session B: current = 10 + 1
    session A: SET powerlevel 11
    session B: SET powerlevel 11
    # In the end we have 11 instead of 12 -> wrong
    

    이제 시계 / MULTI / EXEC 블록을 추가 할 수 있습니다. 시계 절, MULTI 및 EXEC의 명령 값이 변경되지 않은 경우에만 실행된다.

    # Initial arbitrary value
    powerlevel = 10
    session A: WATCH powerlevel
    session B: WATCH powerlevel
    session A: GET powerlevel -> 10
    session B: GET powerlevel -> 10
    session A: current = 10 + 1
    session B: current = 10 + 1
    session A: MULTI
    session B: MULTI
    session A: SET powerlevel 11 -> QUEUED
    session B: SET powerlevel 11 -> QUEUED
    session A: EXEC -> success! powerlevel is now 11
    session B: EXEC -> failure, because powerlevel has changed and was watched
    # In the end, we have 11, and session B knows it has to attempt the transaction again
    # Hopefully, it will work fine this time.
    

    당신은 누구도이 값을 변경하지 않고, 레디 스까지 다시 작업을 다시 시도 할 때까지 기다려야 반복 할 필요가 없습니다 확인 값이 일치하고 신호가 성공한 것입니다.

    은 "거래"경합을 가지고 충분히 빨리와 확률 경우 대부분의 경우, 업데이트는 매우 효율적, 낮습니다. 경합이있는 경우 이제, 몇 가지 추가 작업 (때문에 반복 및 시도에) 일부 "거래"를 수행해야합니다. 그러나 데이터는 항상 일치하고 어떤 잠금이 필요하지 않습니다.

  2. from https://stackoverflow.com/questions/10750626/transactions-and-watch-statement-in-redis by cc-by-sa and MIT license