트랜잭션
작성일
트랜잭션이란
트랜잭션은 데이터베이스의 상태를 변경시키기 위해 수행하는 작업 단위이다. 모든 작업이 성공해서 DB에 정상 반영하는 것을 커밋(commit)
이라 하고, 작업 중 하나라도 실패해서 거래 이전으로 되돌리는 것을 롤백(rollback)
이라 한다.
트랜잭션 특징, ACID
- 원자성(Atomicity): 트랜잭션 내에서 실행한 작업들은 마치 하나의 작업인 것처럼 모두 성공하거나 모두 실패해야 한다. (All or Nothing)
- 일관성(Consistency): 모든 트랜잭션은 일관성 있는 DB 상태를 유지해야 한다. 예를 들어 DB에서 정한 무결성 제약 조건을 항상 만족해야 한다.
- 독립성, 격리성(Isolation): 동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않도록 격리한다. 예를 들어 동시에 같은 데이터를 수정하지 못하도록 해야 한다. 격리성은 동시성과 관련된 성능 이슈로 인해 트랜잭션 격리 수준(Isolation level)을 선택할 수 있다.
- 영속성, 지속성(Durability): 트랜잭션을 성공적으로 끝내면 그 결과가 항상 기록되어야 한다. 중간에 시스템에 문제가 발생해도 DB 로그 등을 사용해서 성공한 트랜잭션 내용을 복구해야 한다.
참고 무결성(Integrity)
무결성이란 데이터의 정확성, 일관성을 의미한다.
데이터에 결함이 없는 상태. 즉, 데이터를 정확하고 일관되게 유지하는 것을 의미한다.
참고 무결성 제약 조건(Integrity Constraint)
무결성 제약조건이란 데이터베이스의 정확성, 일관성을 보장하기 위해 저장, 삭제, 수정 등을 제약하기 위한 조건을 뜻한다. 데이터베이스에 저장된 데이터의 무결성을 보장하고 데이터베이스의 상태를 일관되게 유지하는 것이 주 목적이다.
트랜잭션은 원자성, 일관성, 지속성을 보장한다. 문제는 격리성인데 트랜잭션 간에 격리성을 완벽히 보장하려면 트랜잭션을 거의 순서대로 실행해야 하는데 이렇게 하면 동시 처리 성능이 매우 나빠진다. 이런 문제로 인해 ANSI 표준은 트랜잭션의 격리 수준을 4단계로 나누어 정의했다.
트랜잭션 격리 수준 - Isolation level
- READ UNCOMMITED(커밋되지 않은 읽기)
- READ COMMITTED(커밋된 읽기) - 일반적으로 사용
- REPEATABLE READ(반복 가능한 읽기)
- SERIALIZABLE(직렬화 가능)
데이터베이스 연결 구조와 DB 세션
트랜잭션을 이해하기 위해 데이터베이스 서버 연결 구조와 DB 세션에 대해 알아보자.
사용자는 웹 애플리케이션 서버(WAS)나 DB 접근 툴 같은 클라이언트를 사용해서 데이터베이스 서버에 접근할 수 있다. 클라이언트가 DB 서버에 연결을 요청하고 커넥션을 맺게 되면 DB 서버는 내부에 세션
이라는 것을 만든다. 그리고 앞으로 해당 커넥션을 통한 모든 요청은 이 세션을 통해서 실행하게 된다. 즉, 개발자가 클라이언트를 통해 SQL을 전달하면 현재 커넥션에 연결된 세션이 SQL을 실행한다.
세션은 트랜잭션을 시작하고 커밋, 롤백을 통해 트랜잭션을 종료한다. 그리고 이후에 새로운 트랜잭션을 다시 시작할 수 있다. 사용자가 커넥션을 닫으면 세션은 종료된다. 커넥션 풀이 10개의 커넥션을 생성하면 세션도 10개가 생성된다.
트랜잭션 이해
데이터 변경 쿼리를 실행하고 데이터베이스에 그 결과를 반영하려면 커밋 명령어인 commit
을 호출하고, 결과를 반영하고 싶지 않으면 롤백 명령어인 rollback
을 호출하면 된다.
커밋을 호출하기 전까지는 임시로 데이터를 저장하기 때문에 해당 트랜잭션을 시작한 세션(사용자)에게만 변경 데이터가 보이고 다른 세션(사용자)에게는 변경 데이터가 보이지 않는다.
등록, 수정, 삭제 모두 같은 원리로 동작하며 앞으로는 등록, 수정, 삭제를 간단히 변경이라는 단어로 표현하겠다.
트랜잭션을 사용하려면 자동 커밋
과 수동 커밋
을 이해해야 한다.
트랜잭션 자동/수동 커밋
자동 커밋
자동 커밋으로 설정하면 각각의 쿼리 실행 직후에 자동으로 커밋을 호출한다. 커밋이나 롤백을 직접 호출하지 않아도 되는 편리함이 있지만 쿼리를 하나 실행할 때 마다 자동으로 커밋이 되기 때문에 우리가 원하는 트랜잭션 기능을 제대로 사용할 수 없다. 따라서, 커밋과 롤백을 호출하면서 트랜잭션 기능을 제대로 수행하려면 자동 커밋을 끄고 수동 커밋을 사용해야 한다.
수동 커밋
보통 자동 커밋 모드가 기본으로 설정된 경우가 많기 때문에, 수동 커밋 모드로 설정하는 것을 트랜잭션을 시작한다고 표현할 수 있다. 수동 커밋 설정을 하면 이후에 꼭 commit, rollback을 호출해야 한다.
// 자동 커밋 모드 설정
set autocommit true;
// 수동 커밋 모드 설정
set autocommit false;
commit;