트랜잭션, Commit, Rollback의 개념과 주의사항
트랜잭션은 데이터베이스에서 논리적 기능 수행을 위한 작업의 단위로, ACID 특성을 가지며 Commit과 Rollback을 통해 데이터 일관성을 보장하는 중요한 메커니즘이다.
트랜잭션의 개념과 특성
트랜잭션은 데이터베이스에서 하나의 논리적 기능을 수행하기 위한 작업의 단위이자, 쪼갤 수 없는 업무의 최소 단위다. 여러 개의 작업을 하나로 묶은 실행 유닛으로, 특정 작업으로 시작해서 묶여 있는 모든 작업들을 다 완료해야 정상적으로 종료된다.
ACID 특성
트랜잭션은 데이터베이스의 무결성과 일관성을 보장하기 위해 ACID라는 네 가지 핵심 특성을 갖는다.
원자성(Atomicity)
원자성은 트랜잭션 내의 모든 연산이 모두 성공하거나 모두 실패해야 함을 의미한다.
- “All or Nothing” 원칙 적용
- 트랜잭션에 포함된 작업 중 하나라도 실패하면 전체가 취소됨
- 부분적 실행이 허용되지 않음
예시: 은행 이체 트랜잭션
1. A계좌에서 출금
2. B계좌에 입금
→ 두 작업 중 하나라도 실패하면 전체 트랜잭션이 취소됨
원자성은 트랜잭션의 가장 기본적인 특성으로, 데이터의 부분적 변경으로 인한 불일치를 방지한다.
일관성(Consistency)
일관성은 트랜잭션 실행 전과 후에 데이터베이스가 일관된 상태를 유지해야 함을 의미한다.
- 트랜잭션은 데이터베이스의 무결성 제약조건을 항상 만족해야 함
- 트랜잭션 완료 후 데이터는 비즈니스 규칙을 준수해야 함
- 데이터베이스의 상태는 항상 유효해야 함
💡 예를 들어, 계좌 이체 후에도 모든 계좌 잔액의 합계는 변함없이 유지되어야 한다.
독립성/격리성(Isolation)
독립성은 동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않아야 함을 의미한다.
- 동시에 실행되는 트랜잭션은 서로 격리됨
- 한 트랜잭션의 중간 결과가 다른 트랜잭션에게 보이지 않음
- 격리 수준(Isolation Level)을 통해 제어 가능
격리 수준의 종류:
- READ UNCOMMITTED
- READ COMMITTED
- REPEATABLE READ
- SERIALIZABLE
⚡ 격리성이 낮을수록 동시성은 높아지지만 데이터 일관성 문제가 발생할 가능성이 높아진다.
영속성/지속성(Durability)
영속성은 성공적으로 완료된 트랜잭션의 결과가 영구적으로 반영되어야 함을 의미한다.
- 트랜잭션이 성공적으로 완료되면 그 결과는 시스템 장애가 발생하더라도 보존됨
- 데이터베이스 로그 등을 통해 복구 가능
- 하드웨어 장애나 시스템 충돌에도 데이터 보존
영속성은 시스템 장애가 발생하더라도 커밋된 트랜잭션의 결과가 손실되지 않도록 보장한다.
Commit과 Rollback의 개념
트랜잭션의 결과를 데이터베이스에 반영하거나 취소하는 두 가지 핵심 연산이다.
Commit
Commit은 트랜잭션의 모든 작업이 성공적으로 완료되었음을 선언하고, 변경사항을 데이터베이스에 영구적으로 반영하는 연산이다.
- 트랜잭션의 성공적인 종료를 의미
- 변경사항이 실제 물리적 디스크에 저장됨
- Commit 이후에는 변경사항을 취소할 수 없음
- 다른 트랜잭션에서 변경사항을 볼 수 있게 됨
-- Commit 예시
START TRANSACTION;
UPDATE accounts SET balance = balance - 1000 WHERE account_id = 123;
UPDATE accounts SET balance = balance + 1000 WHERE account_id = 456;
COMMIT;
💡 Commit 연산 후에는 해당 트랜잭션에 의한 모든 변경사항이 데이터베이스에 영구적으로 저장된다.
Rollback
Rollback은 트랜잭션 수행 중 오류가 발생했을 때, 트랜잭션 시작 이전의 상태로 되돌리는 연산이다.
- 트랜잭션의 모든 변경사항을 취소
- 데이터베이스를 트랜잭션 시작 전 상태로 복원
- 트랜잭션 중간에 오류가 발생했을 때 데이터 일관성 유지를 위해 사용
-- Rollback 예시
START TRANSACTION;
UPDATE accounts SET balance = balance - 1000 WHERE account_id = 123;
-- 오류 발생 또는 조건 불만족
ROLLBACK;
Rollback은 트랜잭션 중 오류가 발생했을 때 데이터 일관성을 유지하기 위한 중요한 메커니즘이다.
트랜잭션 사용 시 주의사항
트랜잭션을 효율적으로 사용하기 위해서는 몇 가지 중요한 주의사항을 고려해야 한다.
트랜잭션 범위 최소화
데이터베이스 커넥션 수는 한정적이므로, 트랜잭션의 범위를 최소화하는 것이 중요하다.
- 데이터베이스 커넥션은 제한된 자원
- 트랜잭션이 길어질수록 커넥션 점유 시간 증가
- 다른 서비스가 커넥션을 사용할 수 없어 대기 시간 발생
- 꼭 필요한 작업만 트랜잭션에 포함시켜야 함
// 트랜잭션 범위 최소화 예시
public void processPayment() {
// 트랜잭션 범위 밖에서 수행할 수 있는 작업
validatePaymentData();
preparePaymentInfo();
// 실제 트랜잭션이 필요한 부분만 트랜잭션으로 묶음
transactionManager.executeInTransaction(() -> {
accountService.deductAmount();
paymentService.recordPayment();
});
// 트랜잭션 이후 작업
sendNotification();
}
⚡ 트랜잭션 범위를 최소화하면 데이터베이스 커넥션 사용 효율성이 높아지고 시스템 전체 성능이 향상된다.
자원의 잠금 상태 관리
트랜잭션이 진행 중인 자원은 잠금 상태가 되어 다른 트랜잭션의 접근이 제한된다.
- 트랜잭션이 성공하기 전까지 자원은 잠금 상태 유지
- 잠금 상태가 길어질수록 다른 트랜잭션의 대기 시간 증가
- 데이터베이스의 동시성 저하
- 가능한 빨리 트랜잭션을 완료하여 잠금 해제 필요
자원의 잠금 상태가 길어질수록 시스템의 전반적인 성능이 저하될 수 있으므로, 트랜잭션 처리 시간을 최소화해야 한다.
교착상태(Deadlock) 방지
두 개 이상의 트랜잭션이 서로의 자원을 기다리며 무한정 대기하는 교착상태가 발생할 수 있다.
- 두 트랜잭션이 각각 다른 자원을 점유한 상태에서 서로의 자원을 요청할 때 발생
- 시스템 성능 저하 및 타임아웃 오류 발생 가능
- 트랜잭션을 자주 커밋하여 자원의 잠금 시간 최소화
- 일관된 순서로 자원에 접근하여 교착상태 예방
교착상태 예시:
트랜잭션1: 테이블A 잠금 → 테이블B 잠금 요청(대기)
트랜잭션2: 테이블B 잠금 → 테이블A 잠금 요청(대기)
→ 두 트랜잭션 모두 무한정 대기 상태
💡 교착상태 방지 방법:
- 트랜잭션을 자주 커밋
- 정해진 순서로 테이블에 접근
- 읽기 잠금 획득(SELECT FOR UPDATE) 사용 최소화
- 필요한 경우 타임아웃 설정
트랜잭션은 데이터베이스의 일관성과 무결성을 보장하는 핵심 메커니즘이지만, 효율적인 사용을 위해서는 트랜잭션 범위 최소화, 자원 잠금 관리, 교착상태 방지 등의 주의사항을 고려해야 한다. 적절한 트랜잭션 관리는 시스템의 성능과 안정성에 직접적인 영향을 미친다.
댓글남기기