개념정리4 - 트랜잭션이란?
트랜잭션이란?
트랜잭션의 핵심 개념
트랜잭션(Transaction) 은 데이터베이스에서 하나의 논리적 작업 단위를 의미하며, 데이터베이스의 일관성과 무결성을 보장하는 것이 목적입니다.
트랜잭션의 핵심은 ACID 속성과 관련이 있으며, 이를 기반으로 안정적인 데이터 처리와 복구를 제공합니다.
트랜잭션의 핵심
ACID 속성:
트랜잭션의 본질은 이 4가지 속성을 만족하는 것입니다.Atomicity (원자성):
- 트랜잭션 내의 모든 작업이 완벽히 실행되거나, 전혀 실행되지 않아야 함.
- 중간에 오류가 발생하면 이전 작업들이 모두 취소됩니다.
- 예: 은행 계좌 이체에서 송금과 수취가 모두 이루어져야 하고, 한쪽만 이루어지면 취소.
Consistency (일관성):
- 트랜잭션 실행 전과 후의 데이터 상태가 항상 일관성을 유지해야 함.
- 트랜잭션이 성공하면 데이터는 유효한 상태로 변환되어야 합니다.
- 예: 총 자산이 1000이라면, A 계좌에서 500이 빠지면 B 계좌에 500이 추가되어야 함.
Isolation (독립성):
- 여러 트랜잭션이 동시에 실행되더라도 서로 간섭하지 않아야 함.
- 트랜잭션의 중간 결과는 다른 트랜잭션에서 볼 수 없습니다.
- 예: 하나의 트랜잭션이 데이터를 수정 중일 때, 다른 트랜잭션은 수정이 완료된 데이터만 읽을 수 있음.
Durability (내구성):
- 트랜잭션이 성공적으로 완료되면, 그 결과는 영구적으로 저장되어야 함.
- 시스템 장애가 발생하더라도 저장된 결과는 손실되지 않아야 함.
- 예: 이체가 완료되었다면, 시스템이 재부팅되어도 결과는 유지됨.
트랜잭션의 본질적인 역할
데이터 무결성 보장:
- 트랜잭션은 데이터의 논리적, 구조적 무결성을 유지하기 위한 필수 요소입니다.
실패 복구 메커니즘:
- 작업 도중 오류가 발생하면 모든 변경 사항을 이전 상태로 복구(
ROLLBACK
)하여 데이터 손상을 방지.
- 작업 도중 오류가 발생하면 모든 변경 사항을 이전 상태로 복구(
데이터 동시성 관리:
- 여러 사용자가 동일한 데이터를 동시에 작업할 때, 데이터가 잘못된 상태로 변경되지 않도록 관리.
안정적인 작업 처리:
- 복잡한 작업(예: 여러 테이블에 대한 INSERT/UPDATE/DELETE)을 안전하게 묶어서 처리.
트랜잭션 예제
1. 은행 계좌 이체 예제
- A 계좌에서 500원 출금 → B 계좌에 500원 입금.
트랜잭션 없이 수행할 경우
- A 계좌에서 500원 출금 후, 시스템 오류 발생.
- 결과: A 계좌는 500원이 빠졌지만, B 계좌에 입금되지 않음 → 데이터 불일치.
트랜잭션으로 처리
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 500 WHERE id = 1; -- A 계좌 출금
UPDATE accounts SET balance = balance + 500 WHERE id = 2; -- B 계좌 입금
COMMIT; -- 트랜잭션 성공 시 변경 사항 저장
- 만약 두 번째 작업에서 오류가 발생하면:
ROLLBACK; -- 이전 작업 취소
2. 자바 코드에서 트랜잭션 관리 예제
Connection conn = DriverManager.getConnection(url, username, password);
try {
conn.setAutoCommit(false); // 트랜잭션 시작
PreparedStatement stmt1 = conn.prepareStatement("UPDATE accounts SET balance = balance - 500 WHERE id = ?");
stmt1.setInt(1, 1);
stmt1.executeUpdate();
PreparedStatement stmt2 = conn.prepareStatement("UPDATE accounts SET balance = balance + 500 WHERE id = ?");
stmt2.setInt(1, 2);
stmt2.executeUpdate();
conn.commit(); // 트랜잭션 성공
} catch (SQLException e) {
conn.rollback(); // 실패 시 롤백
} finally {
conn.setAutoCommit(true); // 원래 상태 복구
}
트랜잭션의 중요성
- 트랜잭션은 데이터베이스 작업의 안전성과 신뢰성을 보장합니다.
- 여러 작업을 하나의 작업 단위로 묶어야 하는 경우 트랜잭션은 필수적입니다.
요약: 트랜잭션의 핵심
- 데이터 일관성과 무결성 보장.
- 실패 복구(
ROLLBACK
)와 성공 처리(COMMIT
) 관리. - 동시성 문제를 방지하여 안정적 데이터 관리.
- ACID 속성을 만족하는 것이 트랜잭션의 본질.
트랜잭션은 데이터를 안전하게 다루고 신뢰성을 유지하기 위한 도구입니다.
추가 질문1:
1. 트랜잭션단위는 commit을 실행할 때마다 발생하는가?
2. 시스템 장애란 어떤 경우들을 말하는가?
3. 무결성이란?
1. 트랜잭션 단위는 COMMIT
을 실행할 때마다 발생하는가?
트랜잭션 단위는
COMMIT
이나ROLLBACK
이 실행될 때 종료됩니다.트랜잭션은 데이터베이스 작업의 시작부터 끝까지를 하나의 단위로 묶으며, 트랜잭션 단위란 이러한 작업 그룹을 말합니다.
작동 방식:
- 트랜잭션은 시작(명시적 또는 암묵적)으로 시작됩니다.
- 하나 이상의 SQL 작업(INSERT, UPDATE, DELETE 등)이 실행됩니다.
COMMIT
으로 성공적으로 완료하거나,ROLLBACK
으로 취소하면 트랜잭션이 종료됩니다.- 이후 새 트랜잭션이 시작됩니다.
예:
BEGIN TRANSACTION; UPDATE accounts SET balance = balance - 500 WHERE id = 1; UPDATE accounts SET balance = balance + 500 WHERE id = 2; COMMIT; -- 트랜잭션 종료
- 위 작업은 하나의 트랜잭션 단위.
- 이후 작업은 새 트랜잭션으로 간주.
2. 시스템 장애란 어떤 경우를 말하는가?
시스템 장애의 정의
- 시스템 장애는 데이터베이스나 애플리케이션이 정상적으로 작동하지 못하게 만드는 예상치 못한 문제를 말합니다.
시스템 장애의 주요 예시
하드웨어 장애:
- 하드 디스크 손상, 메모리 오류, 네트워크 연결 문제 등.
소프트웨어 오류:
- 애플리케이션 코드의 버그, 데이터베이스 서버 소프트웨어의 충돌 등.
네트워크 장애:
- 클라이언트와 서버 간 네트워크 연결 중단.
전원 장애:
- 전력 공급 문제로 인해 데이터베이스 작업 중단.
비정상 종료:
- 운영 체제 강제 종료 또는 시스템 충돌.
시스템 장애의 결과
- 트랜잭션 미완료: 트랜잭션이 중간에 중단되어 데이터가 불완전하게 변경될 수 있음.
- 복구 메커니즘: 데이터베이스는 트랜잭션 로그를 사용해 미완료 트랜잭션을 롤백하여 무결성을 유지.
3. 무결성이란?
무결성(Integrity)의 정의
- 무결성은 데이터베이스가 항상 정확하고 일관된 상태를 유지하도록 하는 특성입니다.
- 즉, 데이터가 올바르고, 예상한 대로 저장 및 관리됨을 보장합니다.
무결성의 주요 유형
개체 무결성(Entity Integrity):
- 테이블의 각 행(Row)을 고유하게 식별할 수 있어야 함.
- 예: 기본 키(Primary Key)는 NULL이 아니며, 중복되지 않음.
참조 무결성(Referential Integrity):
- 테이블 간 관계가 항상 유효해야 함.
- 예: 외래 키(Foreign Key)는 참조하는 값이 존재해야 함.
-- 참조 무결성 예 DELETE FROM departments WHERE id = 1; -- 오류: employees 테이블에서 참조 중
도메인 무결성(Domain Integrity):
- 각 열(Column)의 데이터는 허용된 값만 포함해야 함.
- 예: 특정 열은 숫자만 포함해야 한다는 조건.
고유 무결성(Unique Integrity):
- 특정 열 또는 열 조합이 중복되지 않도록 보장.
- 예: 이메일 열은 유일해야 함.
비즈니스 규칙 무결성:
- 특정 비즈니스 규칙을 만족해야 함.
- 예: 은행 계좌 잔액은 0 이상이어야 함.
요약
- 트랜잭션 단위는
COMMIT
또는ROLLBACK
시 종료되며, 새 트랜잭션이 시작됩니다. - 시스템 장애란 하드웨어, 소프트웨어, 네트워크, 전원 문제 등으로 시스템이 정상적으로 동작하지 못하는 상태를 말합니다.
- 무결성은 데이터가 정확하고 일관되게 유지되도록 하는 특성으로, 개체 무결성, 참조 무결성, 도메인 무결성 등이 있습니다.
트랜잭션과 무결성, 장애 복구는 데이터베이스 안정성의 핵심 요소입니다.
추가질문2:
1. 트랜잭션은 여러개가 존재할 수 있어?
트랜잭션은 여러 개가 존재할 수 있는가?
짧은 답변:
- 동시에 여러 트랜잭션이 존재할 수 있습니다.
- 데이터베이스는 다중 사용자 환경을 지원하므로, 여러 클라이언트가 각각의 트랜잭션을 실행할 수 있습니다.
- 단, 한 세션(데이터베이스 연결)에서는 일반적으로 하나의 트랜잭션만 활성 상태일 수 있습니다.
1. 다중 트랜잭션의 동작
다중 사용자 환경:
- 데이터베이스는 여러 사용자(클라이언트)가 동시에 트랜잭션을 실행할 수 있도록 설계되었습니다.
- 각 사용자(클라이언트)가 자신만의 트랜잭션을 처리하며, 데이터베이스는 이를 격리(Isolation)합니다.
단일 세션 내의 트랜잭션:
- 한 세션(Connection)에서 한 번에 하나의 트랜잭션만 활성 상태가 될 수 있습니다.
- 트랜잭션이
COMMIT
또는ROLLBACK
으로 종료되면, 새로운 트랜잭션을 시작할 수 있습니다.
2. 여러 트랜잭션이 동시에 실행될 때의 처리
트랜잭션 격리 수준(Isolation Levels):
- 여러 트랜잭션이 동시에 실행될 때, 데이터 충돌이나 불일치를 방지하기 위해 격리 수준이 사용됩니다.
- 격리 수준의 종류:
- Read Uncommitted:
- 트랜잭션이 커밋되지 않은 데이터를 다른 트랜잭션에서 읽을 수 있음(Dirty Read).
- Read Committed:
- 커밋된 데이터만 읽을 수 있음.
- Repeatable Read:
- 동일 트랜잭션 동안 읽은 데이터가 변경되지 않음.
- Serializable:
- 가장 높은 격리 수준으로, 완전한 데이터 일관성을 보장.
- Read Uncommitted:
예: 다중 트랜잭션의 처리
- 트랜잭션 A:
BEGIN TRANSACTION; UPDATE accounts SET balance = balance - 1000 WHERE id = 1;
- 트랜잭션 B:
BEGIN TRANSACTION; SELECT balance FROM accounts WHERE id = 1;
- 위 작업에서 격리 수준에 따라 트랜잭션 B가 트랜잭션 A의 결과를 볼 수 있는지 결정됩니다.
3. 자바에서 다중 트랜잭션 관리
다중 연결을 사용하는 경우
- 각각의
Connection
객체에서 별도의 트랜잭션이 관리됩니다. - 예제: 두 연결에서 각각 트랜잭션 실행
Connection conn1 = DriverManager.getConnection(url, username, password); Connection conn2 = DriverManager.getConnection(url, username, password);
try {
conn1.setAutoCommit(false); // 트랜잭션 1 시작
conn2.setAutoCommit(false); // 트랜잭션 2 시작
// 트랜잭션 1 작업
PreparedStatement stmt1 = conn1.prepareStatement("UPDATE accounts SET balance = balance - 500 WHERE id = 1");
stmt1.executeUpdate();
// 트랜잭션 2 작업
PreparedStatement stmt2 = conn2.prepareStatement("UPDATE accounts SET balance = balance + 500 WHERE id = 2");
stmt2.executeUpdate();
conn1.commit(); // 트랜잭션 1 커밋
conn2.commit(); // 트랜잭션 2 커밋
} catch (SQLException e) {
conn1.rollback(); // 트랜잭션 1 롤백
conn2.rollback(); // 트랜잭션 2 롤백
} finally {
conn1.close();
conn2.close();
}
#### **하나의 연결에서 트랜잭션 관리**
- 하나의 `Connection`에서 동시에 **다중 트랜잭션은 불가능**하며, 순차적으로 실행해야 합니다.
- **예**:
```java
Connection conn = DriverManager.getConnection(url, username, password);
try {
conn.setAutoCommit(false);
// 트랜잭션 1
PreparedStatement stmt1 = conn.prepareStatement("UPDATE accounts SET balance = balance - 500 WHERE id = 1");
stmt1.executeUpdate();
conn.commit(); // 트랜잭션 1 커밋
// 트랜잭션 2
PreparedStatement stmt2 = conn.prepareStatement("UPDATE accounts SET balance = balance + 500 WHERE id = 2");
stmt2.executeUpdate();
conn.commit(); // 트랜잭션 2 커밋
} catch (SQLException e) {
conn.rollback(); // 현재 트랜잭션 롤백
} finally {
conn.close();
}
4. 트랜잭션과 세션의 관계
- 세션(Session):
- 데이터베이스와의 연결 상태를 유지하는 단일 작업 환경.
- 하나의 세션에서는 일반적으로 하나의 트랜잭션만 활성 상태일 수 있습니다.
- 다중 세션:
- 각 세션이 독립적인 트랜잭션을 처리하므로, 여러 트랜잭션이 동시에 존재 가능합니다.
5. 요약
- 여러 트랜잭션:
- 데이터베이스는 여러 사용자 또는 세션에서 동시에 트랜잭션을 처리 가능.
- 하나의 세션에서는 한 번에 하나의 트랜잭션만 활성 상태.
- 격리 수준:
- 여러 트랜잭션이 동시에 실행될 때, 데이터 충돌을 방지하기 위해 격리 수준 설정.
- 자바에서 다중 트랜잭션:
- 여러
Connection
객체를 사용해 다중 트랜잭션 관리 가능. - 하나의
Connection
에서는 순차적으로 트랜잭션 처리.
- 여러
추가 질문 3:
게임의 저장과 불러오기를 예로 들어서 언제 commit과 rollback이 실행되고 트랜잭션이 쪼개지는가?
게임의 저장(Save)과 불러오기(Load)는 데이터베이스 트랜잭션 개념과 잘 연결될 수 있습니다. 이를 트랜잭션, COMMIT, ROLLBACK과 트랜잭션의 분리(쪼개짐) 측면에서 설명하면 다음과 같습니다.
1. 게임 저장(Save)과 트랜잭션
게임 저장 시 COMMIT
- 게임에서 저장(Save)은 현재 상태를 데이터베이스에 안전하게 기록하는 작업입니다.
- 저장 작업은 트랜잭션으로 묶여 실행되며, 모든 데이터가 성공적으로 기록되었을 때
COMMIT
됩니다.
게임 저장 실패 시 ROLLBACK
- 저장 작업 중 일부가 실패(예: 네트워크 문제, 데이터 손상 등)하면,
ROLLBACK
을 통해 데이터베이스를 이전 상태로 복원합니다. - 이 작업은 데이터 손상(불완전 저장)을 방지합니다.
예: 저장 작업의 트랜잭션 처리
try {
conn.setAutoCommit(false); // 트랜잭션 시작
// 캐릭터 상태 저장
String sql1 = "UPDATE characters SET health = ?, level = ? WHERE id = ?";
PreparedStatement stmt1 = conn.prepareStatement(sql1);
stmt1.setInt(1, 80); // health
stmt1.setInt(2, 5); // level
stmt1.setInt(3, 1); // character ID
stmt1.executeUpdate();
// 인벤토리 상태 저장
String sql2 = "INSERT INTO inventory (character_id, item_id, quantity) VALUES (?, ?, ?)";
PreparedStatement stmt2 = conn.prepareStatement(sql2);
stmt2.setInt(1, 1); // character ID
stmt2.setInt(2, 101); // item ID
stmt2.setInt(3, 10); // quantity
stmt2.executeUpdate();
conn.commit(); // 모든 작업 성공 시 저장
System.out.println("Game saved successfully!");
} catch (Exception e) {
conn.rollback(); // 하나라도 실패하면 롤백
System.out.println("Game save failed. Rolling back...");
}
언제 트랜잭션이 쪼개지나?
- 게임 저장 작업 전체가 한 번의 트랜잭션으로 실행됩니다.
- 작업이 너무 크거나 독립적인 단계로 분리할 필요가 있다면, 여러 트랜잭션으로 나눌 수 있습니다.
- 예: 캐릭터 상태와 인벤토리를 각각 별도 트랜잭션으로 처리.
2. 게임 불러오기(Load)와 트랜잭션
불러오기 작업과 트랜잭션
- 불러오기는 데이터베이스에서 데이터를 읽어오는 작업으로, 일반적으로 트랜잭션이 필요하지 않습니다.
- 이유:
- 데이터 읽기 작업은 데이터베이스 상태를 변경하지 않으므로, 트랜잭션 관리가 필요하지 않음.
- 하지만, 동시성 문제를 방지하거나 중간 상태를 보호하기 위해 트랜잭션을 사용할 수도 있음.
불러오기 작업에서 트랜잭션이 필요할 때
복잡한 읽기 작업이 여러 테이블에 걸쳐 수행되고, 읽기 일관성(Read Consistency)을 보장해야 하는 경우 트랜잭션을 사용.
예: 캐릭터 상태와 인벤토리를 동시에 로드.
try { conn.setAutoCommit(false); // 트랜잭션 시작 // 캐릭터 상태 로드 String sql1 = "SELECT health, level FROM characters WHERE id = ?"; PreparedStatement stmt1 = conn.prepareStatement(sql1); stmt1.setInt(1, 1); // character ID ResultSet rs1 = stmt1.executeQuery(); if (rs1.next()) { System.out.println("Health: " + rs1.getInt("health")); System.out.println("Level: " + rs1.getInt("level")); } // 인벤토리 로드 String sql2 = "SELECT item_id, quantity FROM inventory WHERE character_id = ?"; PreparedStatement stmt2 = conn.prepareStatement(sql2); stmt2.setInt(1, 1); // character ID ResultSet rs2 = stmt2.executeQuery(); while (rs2.next()) { System.out.println("Item: " + rs2.getInt("item_id") + ", Quantity: " + rs2.getInt("quantity")); } conn.commit(); // 불러오기가 성공적으로 완료되면 커밋 } catch (Exception e) { conn.rollback(); // 오류 발생 시 롤백 System.out.println("Failed to load game state. Rolling back..."); }
3. 트랜잭션이 쪼개지는 시점
트랜잭션을 쪼갤 필요가 있을 때
독립적 작업이 많을 때:
- 저장 과정에서 독립적인 작업(캐릭터 상태 저장, 인벤토리 저장 등)이 많아 각각 실패하더라도 나머지 작업은 유지하고 싶다면 트랜잭션을 나눔.
예: 캐릭터 상태와 인벤토리 상태를 별도 트랜잭션으로 처리.
// 캐릭터 상태 저장 트랜잭션 conn1.setAutoCommit(false); conn1.commit(); // 인벤토리 저장 트랜잭션 conn2.setAutoCommit(false); conn2.commit();
성능 최적화가 필요할 때:
- 작업 크기가 커서 한 번에 처리하면 데이터베이스 부하가 클 경우, 작은 트랜잭션 단위로 나눔.
논리적으로 분리된 작업일 때:
- 각 작업이 서로 독립적인 의미를 가질 경우.
- 예: 캐릭터 상태 저장이 실패해도 인벤토리는 저장할 수 있도록 트랜잭션을 분리.
4. 요약
게임 저장 시:
- 모든 데이터를 성공적으로 저장한 후
COMMIT
. - 하나라도 실패하면
ROLLBACK
. - 저장은 일반적으로 하나의 트랜잭션으로 처리되지만, 필요하면 트랜잭션을 나눌 수 있음.
- 모든 데이터를 성공적으로 저장한 후
게임 불러오기 시:
- 트랜잭션이 필요하지 않을 때도 있지만, 읽기 작업의 일관성을 보장하려면 트랜잭션을 사용할 수 있음.
트랜잭션 분리(쪼개기):
- 독립적 작업일 경우, 성능 문제가 있을 경우, 또는 논리적 작업 단위를 나눌 필요가 있을 때 트랜잭션을 나눕니다.
추가 질문4:
1. setAutoCommit이 뭐야?
setAutoCommit
이란?
setAutoCommit
은 JDBC의Connection
객체에서 자동 커밋 모드를 설정하는 메소드입니다.- 기본적으로, JDBC는 SQL 명령이 실행될 때마다 해당 명령을 자동으로 커밋(즉시 데이터베이스에 반영)합니다.
setAutoCommit(false)
를 사용하면 자동 커밋을 비활성화하여, 여러 SQL 명령을 하나의 트랜잭션으로 묶어 제어할 수 있습니다.
setAutoCommit
사용 방식
1. 기본 동작 (자동 커밋 활성화)
- 기본값:
setAutoCommit(true)
(자동 커밋 모드). - SQL 명령이 실행되면 즉시 데이터베이스에 반영됩니다.
Connection conn = DriverManager.getConnection(url, username, password); Statement stmt = conn.createStatement(); stmt.executeUpdate("INSERT INTO users (id, name) VALUES (1, 'John')"); // 자동으로 COMMIT 실행
2. 트랜잭션 관리 (자동 커밋 비활성화)
setAutoCommit(false)
를 사용하면 트랜잭션을 수동으로 제어할 수 있습니다.개발자가 명시적으로
commit()
또는rollback()
을 호출해야 데이터베이스에 변경사항을 반영하거나 취소할 수 있습니다.Connection conn = DriverManager.getConnection(url, username, password); conn.setAutoCommit(false); // 자동 커밋 비활성화 try { Statement stmt = conn.createStatement(); stmt.executeUpdate("UPDATE accounts SET balance = balance - 500 WHERE id = 1"); stmt.executeUpdate("UPDATE accounts SET balance = balance + 500 WHERE id = 2"); conn.commit(); // 성공적으로 트랜잭션 완료 } catch (Exception e) { conn.rollback(); // 오류 발생 시 롤백 } finally { conn.setAutoCommit(true); // 원래 상태로 복구 }
setAutoCommit(false)
가 필요한 이유
1. 트랜잭션 단위로 작업 묶기
- 여러 SQL 명령을 하나의 작업 단위로 묶어서 실행하고, 중간에 실패하면 모든 변경사항을 취소할 수 있습니다.
- 예: 계좌 이체 → 송금과 수취를 동시에 처리.
2. 데이터 일관성 보장
- 한 트랜잭션 내에서 모든 SQL 명령이 성공적으로 실행된 경우에만 데이터를 변경.
- 일부 명령만 실행되고 나머지가 실패하면 롤백.
3. 복잡한 비즈니스 로직 처리
- 비즈니스 로직에 따라 데이터 상태를 제어하거나, 특정 조건에 따라 롤백을 수행.
주의 사항
setAutoCommit(false)
후 반드시commit()
또는rollback()
호출:- 트랜잭션을 명시적으로 종료하지 않으면 데이터베이스에 변경사항이 반영되지 않고, 연결이 닫힐 때까지 락(lock)이 유지될 수 있음.
성능 문제:
- 자동 커밋을 비활성화하면 데이터베이스 락이 길게 유지될 수 있으므로, 트랜잭션을 가능한 짧게 유지해야 함.
요약
setAutoCommit(true)
(기본값):- SQL 명령 실행 시마다 자동으로 커밋.
setAutoCommit(false)
:- 자동 커밋을 비활성화하여, 명시적으로
commit()
이나rollback()
을 호출해야 데이터 변경 반영 또는 취소.
- 자동 커밋을 비활성화하여, 명시적으로
- 사용 이유:
- 여러 작업을 하나의 트랜잭션으로 묶어 데이터 일관성과 무결성을 보장.
추가 질문5:
1. setAutoCommit(true)를 사용하면 좋은 경우와 setAutoCommit(false)를 사용하면 좋은 경우 비교
setAutoCommit(true)
와 setAutoCommit(false)
비교
setAutoCommit(true)
와 setAutoCommit(false)
는 각각 자동 커밋 활성화와 비활성화를 의미하며, 사용 목적에 따라 장단점과 적합한 상황이 다릅니다.
1. setAutoCommit(true)
특징
- SQL 명령이 실행될 때마다 즉시 커밋.
- 개발자가 명시적으로
commit()
이나rollback()
을 호출하지 않아도 됩니다.
장점
간단한 작업 처리:
- 각 명령이 독립적인 작업일 경우 사용하기 적합.
- 트랜잭션 관리 코드를 작성할 필요가 없어 코드가 간단.
성능:
- 짧은 작업에서 성능이 더 빠를 수 있음. 트랜잭션이 길게 유지되지 않아 락(Lock)이 짧게 걸립니다.
안전성:
- 개발자가
commit()
또는rollback()
을 누락하는 실수를 방지.
- 개발자가
적합한 경우
단순 작업:
- 독립적인 INSERT, UPDATE, DELETE 또는 SELECT 작업.
- 예: 로그 데이터 삽입, 단순한 데이터 업데이트.
conn.setAutoCommit(true); Statement stmt = conn.createStatement(); stmt.executeUpdate("INSERT INTO logs (message) VALUES ('System started');");
읽기 전용 작업:
- SELECT 쿼리만 실행하는 경우 트랜잭션이 필요 없으므로 자동 커밋이 적합.
단독 사용자 환경:
- 데이터 충돌 가능성이 없는 단일 사용자 애플리케이션.
2. setAutoCommit(false)
특징
- SQL 명령이 자동으로 커밋되지 않음.
- 트랜잭션이 끝날 때 개발자가 명시적으로
commit()
또는rollback()
을 호출해야 함.
장점
트랜잭션 단위 관리:
- 여러 작업을 하나의 트랜잭션으로 묶어 처리할 수 있어 데이터 일관성을 유지.
부분 실패 처리 가능:
- 작업 중 일부가 실패해도 롤백하여 데이터베이스 상태를 원래대로 복구 가능.
복잡한 비즈니스 로직 처리:
- 여러 작업을 순서대로 수행하고, 조건에 따라 롤백 또는 커밋할 수 있음.
적합한 경우
복잡한 트랜잭션:
- 여러 SQL 작업이 논리적으로 묶여야 할 때.
- 예: 은행 계좌 이체, 재고 관리.
conn.setAutoCommit(false); try { stmt.executeUpdate("UPDATE accounts SET balance = balance - 1000 WHERE id = 1"); stmt.executeUpdate("UPDATE accounts SET balance = balance + 1000 WHERE id = 2"); conn.commit(); // 모든 작업 성공 시 } catch (Exception e) { conn.rollback(); // 작업 실패 시 }
데이터 일관성이 중요한 경우:
- 여러 작업이 반드시 하나의 단위로 실행되어야 할 때.
- 예: 주문 생성과 재고 감소 작업.
동시성 제어:
- 여러 사용자가 동시에 데이터를 변경할 가능성이 높은 환경에서 사용.
- 트랜잭션이 완료될 때까지 다른 사용자가 수정할 수 없도록 보장.
3. setAutoCommit(true)
vs setAutoCommit(false)
비교
특징 | setAutoCommit(true) |
setAutoCommit(false) |
---|---|---|
커밋 시점 | SQL 명령 실행 직후 자동 커밋. | 명시적으로 commit() 또는 rollback() 호출 필요. |
사용 난이도 | 간단. 추가적인 트랜잭션 관리 코드가 필요 없음. | 개발자가 직접 트랜잭션을 관리해야 하므로 복잡. |
데이터 일관성 관리 | 여러 작업이 논리적으로 연결되어 있지 않을 경우 적합. | 여러 작업을 하나의 트랜잭션으로 묶어 데이터 일관성을 보장. |
롤백 가능 여부 | 실패 시 개별 SQL 명령에 대해 롤백 불가. | 실패 시 트랜잭션 전체를 롤백 가능. |
적합한 작업 유형 | 단순한 INSERT, UPDATE, DELETE, SELECT. | 복잡한 트랜잭션 처리(예: 계좌 이체, 주문 생성 등). |
성능 | 짧고 단순한 작업에서는 더 빠름. | 긴 트랜잭션 작업에서 성능 저하 가능(락 유지). |
락(Lock) | SQL 명령 실행 후 즉시 해제. | 트랜잭션이 종료될 때까지 유지 가능. |
4. 결론
setAutoCommit(true)
를 사용하는 경우:- SQL 명령이 독립적이고 간단하며, 트랜잭션의 복잡한 관리가 필요 없는 상황.
- 예: 단순 데이터 로깅, 사용자 정보 업데이트.
setAutoCommit(false)
를 사용하는 경우:- 여러 작업을 하나의 논리적 단위로 묶어야 하거나, 데이터 일관성과 무결성이 중요한 경우.
- 예: 계좌 이체, 주문 생성, 다중 테이블 조작.
둘 중 무엇을 사용할지는 애플리케이션의 요구사항(복잡도, 데이터 일관성, 성능 요구사항)에 따라 결정해야 합니다.