>  기사  >  데이터 베이스  >  Redis Pit 예방 가이드 - 트랜잭션

Redis Pit 예방 가이드 - 트랜잭션

王林
王林앞으로
2021-01-27 09:14:062138검색

Redis Pit 예방 가이드 - 트랜잭션

관련 명령어 소개:

(동영상 공유 학습: redis 동영상 튜토리얼)

Redis Pit 예방 가이드 - 트랜잭션

참고:

------MULTI, EXEC, DISCARD는 트랜잭션을 명시적으로 열고 제어하는 ​​명령어입니다. 일반적으로 사용되는 명령은 관계형 데이터베이스의 BEGAIN, COMMIT, ROLLBACK과 비교할 수 있습니다(실제로는 큰 차이가 있습니다).

------WATCH 명령의 사용은 반복 불가능한 읽기 및 팬텀 읽기를 해결하는 것입니다. 트랜잭션 동시성 문제(단순히 키 잠금으로 이해됨)로 인해 발생합니다.

Redis 트랜잭션

MULTI, EXEC, DISCARD 및 WATCH는 Redis 트랜잭션의 기초입니다. 트랜잭션을 명시적으로 시작하고 제어하는 ​​데 사용되며 한 단계에서 일련의 명령을 실행할 수 있습니다. 그리고 두 가지 중요한 보장을 제공합니다.

트랜잭션의 모든 명령은 직렬화되어 순서대로 실행됩니다. Redis 트랜잭션을 실행하는 동안 다른 클라이언트에서 발행한 요청은 발생하지 않습니다. 이렇게 하면 명령 대기열이 단일 원자성 작업으로 실행됩니다.

큐의 명령은 모두 처리되거나 무시됩니다. EXEC 명령은 트랜잭션의 모든 명령 실행을 트리거합니다. 따라서 클라이언트가 트랜잭션 컨텍스트에서 서버와의 연결이 끊어진 경우 MULTI 명령이 호출되기 전에 발생하면 EXEC 명령이 실행되지 않습니다. 그러면 모든 명령이 실행됩니다.

동시에 redis는 AOF(추가 전용 파일)를 사용하여 추가 쓰기 작업을 통해 디스크에 트랜잭션을 씁니다. 다운타임이나 프로세스 충돌이 발생하면 서비스가 정상적으로 시작되고 일부 작업을 재개할 수 있도록 redis-check-aof 도구를 사용하여 추가 전용 파일을 복구할 수 있습니다.

Usage

MULTI 명령을 사용하여 Redis 트랜잭션을 명시적으로 시작합니다. 이 명령은 항상 OK로 응답합니다. 이 시점에서 사용자는 여러 명령을 실행할 수 있으며 Redis는 이러한 명령을 실행하지 않고 대기열에 추가합니다. EXEC가 호출되면 모든 명령이 실행됩니다. DISCARD를 호출하면 트랜잭션의 명령 대기열을 지우고 트랜잭션을 종료할 수 있습니다.

다음 예에서는 foo 및 bar 키를 원자적으로 증가시킵니다.

>MULTI
OK
>INCR foo
QUEUED
>INCR bar
QUEUED
>EXEC
1)(整数)1
2)(整数)1

위 명령 실행에서 볼 수 있듯이 EXEC는 배열을 반환합니다. 여기서 각 요소는 트랜잭션의 단일 명령에 대한 반환 결과이며 순서는 명령이 실행된 순서와 동일합니다. Redis 연결이 MULTI 요청의 컨텍스트에 있을 때 모든 명령은 QUEUED 문자열(Redis 프로토콜의 관점에서 상태 응답으로 전송됨)로 응답되고 명령 대기열에 대기됩니다. EXEC가 호출될 때만 대기열에 있는 명령이 실행되며 이때 실제 결과가 반환됩니다.

트랜잭션 오류

트랜잭션 중에 두 가지 종류의 명령 오류가 발생할 수 있습니다.

EXEC 명령을 호출하기 전에 오류가 발생했습니다(COMMAND 대기열 실패). 예를 들어, 명령에 구문 오류(잘못된 매개변수 수, 잘못된 명령 이름...)가 있거나 메모리 부족(서버에 maxmemory 지시어를 사용하여 메모리 제한이 있는 경우)과 같은 특정 심각한 조건이 있을 수 있습니다.

클라이언트는 EXEC를 호출하기 전에 첫 번째 오류를 감지합니다. 대기열에 있는 명령의 상태 응답을 확인하여(***참고: 이는 실행 결과가 아니라 대기열에 있는 상태 응답을 나타냄***) 명령이 QUEUED로 응답하면 올바르게 대기열에 추가된 것입니다. 그렇지 않으면 Redis는 다음을 반환합니다. 오류. 명령을 대기열에 넣는 동안 오류가 발생하면 대부분의 클라이언트는 트랜잭션을 중단하고 명령 대기열을 지웁니다. 그러나:

Redis 2.6.5 이전에는 EXEC 명령이 호출된 후 클라이언트가 이전 오류를 무시하고 명령의 하위 집합(성공적으로 대기열에 추가된 명령)을 실행했습니다. Redis 2.6.5부터 서버는 명령이 누적되는 동안 발생한 오류를 기억하고 EXEC 명령이 호출되면 트랜잭션 실행을 거부하고 이러한 오류를 반환하는 동시에 명령 대기열을 자동으로 지웁니다. 예는 다음과 같습니다:

>MULTI
+OK
>INCR a b c
-ERR wrong number of arguments for 'incr' command

이는 INCR 명령의 구문 오류로 인해 발생하며 EXEC를 호출하고 트랜잭션을 종료하기 전에 감지됩니다(버전2.6.5+).

EXEC 명령을 호출한 후 오류가 발생했습니다. 예를 들어 잘못된 값을 사용하여 키에 대한 작업을 수행하는 경우(예: 문자열 값에 대한 List 작업 호출)

EXEC 명령 실행 후 발생하는 오류는 특별히 처리되지 않습니다. 트랜잭션이 실행되지 않아도 다른 명령은 정상적으로 실행됩니다.

예제는 다음과 같습니다.

>MULTI
+OK
>SET a 3
+QUEUED
>LPOP a
+QUEUED
>EXEC
*2
+OK
-ERR Operation against a key holding the wrong kind of value

EXEC는 두 요소가 포함된 문자열 배열을 반환합니다. 한 요소는 OK이고 다른 요소는 -ERR...입니다. 오류가 사용자에게 제대로 피드백될 수 있는지 여부는 클라이언트 라이브러리(예: Spring-data-redis.redisTemplate)의 구현에 따라 다릅니다. 명령이 실패하더라도 대기열의 다른 모든 명령은 처리됩니다. Redis는 명령 처리를 중지하지 않습니다.

Redis 트랜잭션은 롤백(강조)을 지원하지 않습니다.

실제로 트랜잭션 실행 중에 Redis 명령이 실패할 수 있지만 나머지 명령은 롤백(트랜잭션 롤백) 대신 계속 실행됩니다. 관계형 데이터베이스를 사용해 본 적이 있다면 이 상황이 이상하게 보일 수 있습니다. 하지만 이 상황에 대한 좋은 설명이 있습니다.

Redis命令可能会执行失败,仅仅是由于错误的语法被调用(命令排队时检测不出来的错误),或者使用错误的数据类型操作某个Key: 这意味着,实际上失败的命令都是编程错误造成的,都是开发中能够被检测出来的,生产环境中不应该存在。(这番话,彻底甩锅,“都是你们自己编程错误,与我们无关”。)由于不必支持Rollback,Redis内部简洁并且更加高效。

“如果错误就是发生了呢?”这是一个反对Redis观点的争论。然而应该指出的是,通常情况下,回滚并不能挽救编程错误。鉴于没有人能够挽救程序员的错误,并且Redis命令失败所需的错误类型不太可能进入生产环境,所以我们选择了不支持错误回滚(Rollback)这种更简单快捷的方法。

清除命令队列

DISCARD被用来中止事务。事务中的所有命令将不会被执行,连接将恢复正常状态。

> SET foo 1
OK
> MULTI
OK
> INCR foo
QUEUED
> DISCARD
OK
> GET foo
"1"

相关推荐:redis数据库教程

위 내용은 Redis Pit 예방 가이드 - 트랜잭션의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.im에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제