복붙노트

[REDIS] 어떻게 루비에서 MULTI 블록 내부 레디 스에서 읽을 수 있습니까?

REDIS

어떻게 루비에서 MULTI 블록 내부 레디 스에서 읽을 수 있습니까?

나는 MULTI 거래에서 레디 스 명령의 복잡한 설정을 캡슐화 합니다만, 트랜잭션의 논리는 레디 스에 이미 값에 따라 달라집니다. 그러나 모든 트랜잭션 내에서 읽고 전무를 반환하는 것

여기에 문제를 보여줍니다 예입니다 :

[Dev]> $redis.set("foo", "bar")
=> "OK"
[Dev]> $redis.multi{ $redis.set("foo", "baz") if $redis.get("foo") == "bar" }
=> ["bar"]
[Dev]> $redis.get("foo")
=> "bar"

분명 내가 마지막 반환 값이 '바즈'가되고 싶어요 - 내가 어떻게 이것을 달성 할 수 있습니까?

해결법

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

    1.(GET 포함) 모든 명령이 실제로 간부 시간에 실행되기 때문에 당신은 할 수 없습니다. 이 경우, get 명령은 미래의 객체가 아닌 실제 값을 반환합니다.

    (GET 포함) 모든 명령이 실제로 간부 시간에 실행되기 때문에 당신은 할 수 없습니다. 이 경우, get 명령은 미래의 객체가 아닌 실제 값을 반환합니다.

    트랜잭션을 구현하는 방법은 두 가지가 있습니다.

    시계 절을 사용하여

    시계 절은 동시 업데이트를 방지하는 데 사용됩니다. 변수의 값은 시계 멀티 절 사이에 업데이트되는 경우, 상기 다중 블록 내의 명령은인가되지 않는다. 그것은 트랜잭션 또 다른 시간을 시도하는 클라이언트까지입니다.

    loop do
        $redis.watch "foo" 
        val = $redis.get("foo")
        if val == "bar" then
            res = $redis.multi do |r|
                r.set("foo", "baz") 
            end
            break if res
        else
            $redis.unwatch "foo"
            break
        end
    end
    

    다음은 스크립트 블록의 내용이 비어있을 수 있기 때문에 조금 복잡하므로이 트랜잭션이 취소되었는지 여부를 알 수있는 쉬운 방법은 없다, 또는 전혀 발생하지 않았다 여부. 멀티 블록은 트랜잭션이 취소 된 경우를 제외한 모든 경우에 결과를 반환 할 때 그것은 일반적으로 더 쉽다.

    루아 서버 측 스크립트를 사용하여

    레디 스 2.6 이상으로, 루아 스크립트는 서버에서 실행 할 수 있습니다. 전체 스크립트의 실행은 원자이다. 그것은 쉽게 루비에서 구현 될 수있다 :

    cmd = <<EOF
        if redis.call('get',KEYS[1]) == ARGV[1] then
           redis.call('set',KEYS[1],ARGV[2] )
        end
    EOF
    $redis.eval cmd, 1, "foo", "bar", "baz"
    

    이것은 일반적으로 시계 절을 사용하는 것보다 훨씬 간단합니다.

  2. ==============================

    2.세르지오 그의 코멘트에 언급, 당신은 선택적으로 레디 스에서 그런 MULTI 블록을 실행할 수 없습니다. 거래 설명서를 참조하십시오 :

    세르지오 그의 코멘트에 언급, 당신은 선택적으로 레디 스에서 그런 MULTI 블록을 실행할 수 없습니다. 거래 설명서를 참조하십시오 :

    당신은, 그러나, 체크인 및 세트 (의사 코드)를 사용하여 낙관적 잠금을 구현하기 위해 시계를 사용할 수 있습니다 :

    SET foo bar
    WATCH foo
    $foo = GET foo
    MULTI
    if $foo == 'bar'
      SET foo baz
    EXEC
    GET foo
    

    감시 키 (들)이 변경되지 않은 경우 시계를 사용하여 트랜잭션에만 실행됩니다. 시계 키가 변경되는 경우, EXEC가 실패하고 다시 시도 할 수 있습니다.

    또 다른 가능성은 스크립팅 기능을 사용하지만이 2.6 릴리스 후보에서만 사용할 수 있습니다.

  3. from https://stackoverflow.com/questions/11300958/how-can-i-read-from-redis-inside-a-multi-block-in-ruby by cc-by-sa and MIT license