Redis ‐ Redis Transaction ACID - thought-corner/Backend-PlayGround GitHub Wiki
Redis - Redis Transaction ACID
1. 명령 일괄 실행 : MULTI와 EXEC
- 동작 :
MULTI명령어를 날리면 트랜잭션이 시작된다. 이후 들어오는 명령어들은 즉시 실행되지 않고 큐에 차곡차곡 쌓인다. 마지막에EXEC를 호출하는 순간, 쌓여있던 모든 명령어가 순차적으로 한꺼번에 실행된다. - 격리성 : Redis는 기본적으로 싱글 쓰레드 기반으로 동작하기 때문에
EXEC가 실행되어 큐의 명령들이 처리되는 동안 다른 클라이언트의 명령은 중간에 끼어들 수 없다. 덕분에 작업의 독립성이 보장된다.
2. 원자성(Atomicity)
- Redis는 롤백(Rollback)을 지원하지 않는다.
- 명령어 구문 오류(Syntax Error)는
EXEC전에 걸러지지만, 실행 중 에러가 발생하면 에러가 난 명령어만 실패하고 나머지는 그대로 반영된다. - Redis는 성능 극대화를 지향하며, 롤백을 지원하지 않음으로써 시스템을 훨씬 단순하고 빠르게 유지한다.
3. WATCH : 낙관적 잠금(Optimistic Locking)
- 동작 :
MULTI를 시작하기 전에 특정 키를WATCH한다. 만약EXEC를 호출하기 전까지 다른 클라이언트가 내가 감시하던 키를 수정했다면, 내 트랜잭션은 통째로 취소된다. - 낙관적 잠금 : 작업하는 동안 아무도 수정하지 않았다는 것을 낙관적으로 가정하고 마지막에 검사하는 방식이다. 무거운 자원 잠금 방식을 사용하지 않아 성능상 이점이 크다.
1. 트랜잭션의 생명 주기
- 시작 : MULTI - 클라이언트가
MULTI명령을 보내면 Redis는 해당 연결을 트랜잭션 모드로 전환한다. 이제부터 들어오는 명령들은 즉시 실행되지 않는다. - 대기 : 명령 큐잉(Queuing) -
MULTI이후 들어오는 모든 명령어는 서버 명령 큐에 순서대로 쌓인다. 이 단계에서 문법 오류가 발견되면 트랜잭션 자체가 무효화되기도 한다. - 실행 트리거 : EXEC - 모든 명령을 큐에 담은 후 클라이언트가
EXEC명령을 보낸다. 이 명령이 도착하는 순간 실제 연산이 일어난다. - 순차 실행 및 결과 반환 - Redis 서버는 큐에 쌓인 명령들을 하나씩 순서대로 실행해 격리성을 확보하고 모든 명령 실행이 완료되면 각 명령 결괏값들을 모아 하나의 배열 형태로 클라이언트에게 반환한다.
1. Atomicity(원자성) : "부분적 지원"
- 트랜잭션 내의 명령어가 전부 성공하거나 전부 실패해야 한다는 원칙이다.
- Redis의 현실 :
MULTI - EXEC를 묶어서 실행하는 것까지 지원한다. 하지만 롤백이 없다. 중간에 특정 명령어가 실행 중 에러가 나더라도 이미 성공한 명령어는 그대로 남고 뒤의 명령어도 계속 실행된다.
2. Consistency(일관성) : "애플리케이션 책임"
- 트랜잭션 전후 데이터 상태가 비즈니스 규칙에 맞게 유효해야 한다는 원칙이다.
- RDBMS처럼 강력한 스키마 제약 조건이 없고 Redis는 데이터 타입이 맞는지 정도만 체크해준다.
- 결국 데이터가 논리적으로 올바른가를 Redis가 아니라 애플리케이션에서 직접 검증하고 관리해야 한다.
3. Isolation(격리성) : "완전 지원"
- 동시에 실행되는 트랜잭션들이 서로 간섭하지 못하게 격리되어야 한다는 원칙이다.
- Redis는 기본적으로 싱글 쓰레드 기반으로 동작하기 때문에 격리성이 완전 보장된다.
EXEC가 실행되는 동안 다른 클라이언트 명령은 줄을 서서 기다려야 한다. 즉, 트랜잭션 도중에 다른 트랜잭션이 끼어들 여지가 물리적으로 차단되어 있어 완벽한 격리가 이루어지는 것이다.
4. Durability(지속성) : "설정 의존"
- 성공적으로 완료된 트랜잭션의 결과는 시스템이 장애가 나더라도 영구적으로 보존되어야 한다는 점이다.
- Redis는 기본적으로 인메모리(In-Memory) 기반이기 때문에 설정을 건드리지 않으면 지속성을 보장하지 않는다.
- AOF/RDB 설정을 어떻게 하느냐에 따라 보존 수준이 달라진다.