웹 백엔드/개념정리

개념정리4 - 트랜잭션이란?

Blue_bull 2025. 1. 19. 23:30

트랜잭션이란?

트랜잭션의 핵심 개념

트랜잭션(Transaction)데이터베이스에서 하나의 논리적 작업 단위를 의미하며, 데이터베이스의 일관성무결성을 보장하는 것이 목적입니다.
트랜잭션의 핵심은 ACID 속성과 관련이 있으며, 이를 기반으로 안정적인 데이터 처리와 복구를 제공합니다.


트랜잭션의 핵심

  1. ACID 속성:
    트랜잭션의 본질은 이 4가지 속성을 만족하는 것입니다.

    • Atomicity (원자성):

      • 트랜잭션 내의 모든 작업이 완벽히 실행되거나, 전혀 실행되지 않아야 함.
      • 중간에 오류가 발생하면 이전 작업들이 모두 취소됩니다.
      • : 은행 계좌 이체에서 송금과 수취가 모두 이루어져야 하고, 한쪽만 이루어지면 취소.
    • Consistency (일관성):

      • 트랜잭션 실행 전과 후의 데이터 상태가 항상 일관성을 유지해야 함.
      • 트랜잭션이 성공하면 데이터는 유효한 상태로 변환되어야 합니다.
      • : 총 자산이 1000이라면, A 계좌에서 500이 빠지면 B 계좌에 500이 추가되어야 함.
    • Isolation (독립성):

      • 여러 트랜잭션이 동시에 실행되더라도 서로 간섭하지 않아야 함.
      • 트랜잭션의 중간 결과는 다른 트랜잭션에서 볼 수 없습니다.
      • : 하나의 트랜잭션이 데이터를 수정 중일 때, 다른 트랜잭션은 수정이 완료된 데이터만 읽을 수 있음.
    • Durability (내구성):

      • 트랜잭션이 성공적으로 완료되면, 그 결과는 영구적으로 저장되어야 함.
      • 시스템 장애가 발생하더라도 저장된 결과는 손실되지 않아야 함.
      • : 이체가 완료되었다면, 시스템이 재부팅되어도 결과는 유지됨.

트랜잭션의 본질적인 역할

  1. 데이터 무결성 보장:

    • 트랜잭션은 데이터의 논리적, 구조적 무결성을 유지하기 위한 필수 요소입니다.
  2. 실패 복구 메커니즘:

    • 작업 도중 오류가 발생하면 모든 변경 사항을 이전 상태로 복구(ROLLBACK)하여 데이터 손상을 방지.
  3. 데이터 동시성 관리:

    • 여러 사용자가 동일한 데이터를 동시에 작업할 때, 데이터가 잘못된 상태로 변경되지 않도록 관리.
  4. 안정적인 작업 처리:

    • 복잡한 작업(예: 여러 테이블에 대한 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); // 원래 상태 복구
}

트랜잭션의 중요성

  • 트랜잭션은 데이터베이스 작업의 안전성과 신뢰성을 보장합니다.
  • 여러 작업을 하나의 작업 단위로 묶어야 하는 경우 트랜잭션은 필수적입니다.

요약: 트랜잭션의 핵심

  1. 데이터 일관성과 무결성 보장.
  2. 실패 복구(ROLLBACK)와 성공 처리(COMMIT) 관리.
  3. 동시성 문제를 방지하여 안정적 데이터 관리.
  4. ACID 속성을 만족하는 것이 트랜잭션의 본질.

트랜잭션은 데이터를 안전하게 다루고 신뢰성을 유지하기 위한 도구입니다.

추가 질문1:

1. 트랜잭션단위는 commit을 실행할 때마다 발생하는가?

2. 시스템 장애란 어떤 경우들을 말하는가?

3. 무결성이란?

1. 트랜잭션 단위는 COMMIT을 실행할 때마다 발생하는가?

  • 트랜잭션 단위는 COMMIT이나 ROLLBACK이 실행될 때 종료됩니다.

  • 트랜잭션은 데이터베이스 작업의 시작부터 끝까지를 하나의 단위로 묶으며, 트랜잭션 단위란 이러한 작업 그룹을 말합니다.

  • 작동 방식:

    1. 트랜잭션은 시작(명시적 또는 암묵적)으로 시작됩니다.
    2. 하나 이상의 SQL 작업(INSERT, UPDATE, DELETE 등)이 실행됩니다.
    3. COMMIT으로 성공적으로 완료하거나, ROLLBACK으로 취소하면 트랜잭션이 종료됩니다.
    4. 이후 새 트랜잭션이 시작됩니다.
  • :

    BEGIN TRANSACTION;
    UPDATE accounts SET balance = balance - 500 WHERE id = 1;
    UPDATE accounts SET balance = balance + 500 WHERE id = 2;
    COMMIT; -- 트랜잭션 종료
    • 위 작업은 하나의 트랜잭션 단위.
    • 이후 작업은 새 트랜잭션으로 간주.

2. 시스템 장애란 어떤 경우를 말하는가?

시스템 장애의 정의

  • 시스템 장애는 데이터베이스나 애플리케이션이 정상적으로 작동하지 못하게 만드는 예상치 못한 문제를 말합니다.

시스템 장애의 주요 예시

  1. 하드웨어 장애:

    • 하드 디스크 손상, 메모리 오류, 네트워크 연결 문제 등.
  2. 소프트웨어 오류:

    • 애플리케이션 코드의 버그, 데이터베이스 서버 소프트웨어의 충돌 등.
  3. 네트워크 장애:

    • 클라이언트와 서버 간 네트워크 연결 중단.
  4. 전원 장애:

    • 전력 공급 문제로 인해 데이터베이스 작업 중단.
  5. 비정상 종료:

    • 운영 체제 강제 종료 또는 시스템 충돌.

시스템 장애의 결과

  • 트랜잭션 미완료: 트랜잭션이 중간에 중단되어 데이터가 불완전하게 변경될 수 있음.
  • 복구 메커니즘: 데이터베이스는 트랜잭션 로그를 사용해 미완료 트랜잭션을 롤백하여 무결성을 유지.

3. 무결성이란?

무결성(Integrity)의 정의

  • 무결성은 데이터베이스가 항상 정확하고 일관된 상태를 유지하도록 하는 특성입니다.
  • 즉, 데이터가 올바르고, 예상한 대로 저장 및 관리됨을 보장합니다.

무결성의 주요 유형

  1. 개체 무결성(Entity Integrity):

    • 테이블의 각 행(Row)을 고유하게 식별할 수 있어야 함.
    • : 기본 키(Primary Key)는 NULL이 아니며, 중복되지 않음.
  2. 참조 무결성(Referential Integrity):

    • 테이블 간 관계가 항상 유효해야 함.
    • : 외래 키(Foreign Key)는 참조하는 값이 존재해야 함.
      -- 참조 무결성 예
      DELETE FROM departments WHERE id = 1; -- 오류: employees 테이블에서 참조 중
  3. 도메인 무결성(Domain Integrity):

    • 각 열(Column)의 데이터는 허용된 값만 포함해야 함.
    • : 특정 열은 숫자만 포함해야 한다는 조건.
  4. 고유 무결성(Unique Integrity):

    • 특정 열 또는 열 조합이 중복되지 않도록 보장.
    • : 이메일 열은 유일해야 함.
  5. 비즈니스 규칙 무결성:

    • 특정 비즈니스 규칙을 만족해야 함.
    • : 은행 계좌 잔액은 0 이상이어야 함.

요약

  1. 트랜잭션 단위는 COMMIT 또는 ROLLBACK 시 종료되며, 새 트랜잭션이 시작됩니다.
  2. 시스템 장애란 하드웨어, 소프트웨어, 네트워크, 전원 문제 등으로 시스템이 정상적으로 동작하지 못하는 상태를 말합니다.
  3. 무결성은 데이터가 정확하고 일관되게 유지되도록 하는 특성으로, 개체 무결성, 참조 무결성, 도메인 무결성 등이 있습니다.

트랜잭션과 무결성, 장애 복구는 데이터베이스 안정성의 핵심 요소입니다.

추가질문2:

1. 트랜잭션은 여러개가 존재할 수 있어?

트랜잭션은 여러 개가 존재할 수 있는가?

짧은 답변:

  • 동시에 여러 트랜잭션이 존재할 수 있습니다.
    • 데이터베이스는 다중 사용자 환경을 지원하므로, 여러 클라이언트가 각각의 트랜잭션을 실행할 수 있습니다.
    • 단, 한 세션(데이터베이스 연결)에서는 일반적으로 하나의 트랜잭션만 활성 상태일 수 있습니다.

1. 다중 트랜잭션의 동작

  1. 다중 사용자 환경:

    • 데이터베이스는 여러 사용자(클라이언트)가 동시에 트랜잭션을 실행할 수 있도록 설계되었습니다.
    • 각 사용자(클라이언트)가 자신만의 트랜잭션을 처리하며, 데이터베이스는 이를 격리(Isolation)합니다.
  2. 단일 세션 내의 트랜잭션:

    • 한 세션(Connection)에서 한 번에 하나의 트랜잭션만 활성 상태가 될 수 있습니다.
    • 트랜잭션이 COMMIT 또는 ROLLBACK으로 종료되면, 새로운 트랜잭션을 시작할 수 있습니다.

2. 여러 트랜잭션이 동시에 실행될 때의 처리

트랜잭션 격리 수준(Isolation Levels):

  • 여러 트랜잭션이 동시에 실행될 때, 데이터 충돌이나 불일치를 방지하기 위해 격리 수준이 사용됩니다.
  • 격리 수준의 종류:
    1. Read Uncommitted:
      • 트랜잭션이 커밋되지 않은 데이터를 다른 트랜잭션에서 읽을 수 있음(Dirty Read).
    2. Read Committed:
      • 커밋된 데이터만 읽을 수 있음.
    3. Repeatable Read:
      • 동일 트랜잭션 동안 읽은 데이터가 변경되지 않음.
    4. Serializable:
      • 가장 높은 격리 수준으로, 완전한 데이터 일관성을 보장.

예: 다중 트랜잭션의 처리

  • 트랜잭션 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. 요약

  1. 여러 트랜잭션:
    • 데이터베이스는 여러 사용자 또는 세션에서 동시에 트랜잭션을 처리 가능.
    • 하나의 세션에서는 한 번에 하나의 트랜잭션만 활성 상태.
  2. 격리 수준:
    • 여러 트랜잭션이 동시에 실행될 때, 데이터 충돌을 방지하기 위해 격리 수준 설정.
  3. 자바에서 다중 트랜잭션:
    • 여러 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. 트랜잭션이 쪼개지는 시점

트랜잭션을 쪼갤 필요가 있을 때

  1. 독립적 작업이 많을 때:

    • 저장 과정에서 독립적인 작업(캐릭터 상태 저장, 인벤토리 저장 등)이 많아 각각 실패하더라도 나머지 작업은 유지하고 싶다면 트랜잭션을 나눔.

    : 캐릭터 상태와 인벤토리 상태를 별도 트랜잭션으로 처리.

    // 캐릭터 상태 저장 트랜잭션
    conn1.setAutoCommit(false);
    conn1.commit();
    
    // 인벤토리 저장 트랜잭션
    conn2.setAutoCommit(false);
    conn2.commit();
  2. 성능 최적화가 필요할 때:

    • 작업 크기가 커서 한 번에 처리하면 데이터베이스 부하가 클 경우, 작은 트랜잭션 단위로 나눔.
  3. 논리적으로 분리된 작업일 때:

    • 각 작업이 서로 독립적인 의미를 가질 경우.
    • 예: 캐릭터 상태 저장이 실패해도 인벤토리는 저장할 수 있도록 트랜잭션을 분리.

4. 요약

  1. 게임 저장 시:

    • 모든 데이터를 성공적으로 저장한 후 COMMIT.
    • 하나라도 실패하면 ROLLBACK.
    • 저장은 일반적으로 하나의 트랜잭션으로 처리되지만, 필요하면 트랜잭션을 나눌 수 있음.
  2. 게임 불러오기 시:

    • 트랜잭션이 필요하지 않을 때도 있지만, 읽기 작업의 일관성을 보장하려면 트랜잭션을 사용할 수 있음.
  3. 트랜잭션 분리(쪼개기):

    • 독립적 작업일 경우, 성능 문제가 있을 경우, 또는 논리적 작업 단위를 나눌 필요가 있을 때 트랜잭션을 나눕니다.

추가 질문4:

1. setAutoCommit이 뭐야?

setAutoCommit이란?

  • setAutoCommitJDBC의 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. 복잡한 비즈니스 로직 처리

  • 비즈니스 로직에 따라 데이터 상태를 제어하거나, 특정 조건에 따라 롤백을 수행.

주의 사항

  1. setAutoCommit(false) 후 반드시 commit() 또는 rollback() 호출:

    • 트랜잭션을 명시적으로 종료하지 않으면 데이터베이스에 변경사항이 반영되지 않고, 연결이 닫힐 때까지 락(lock)이 유지될 수 있음.
  2. 성능 문제:

    • 자동 커밋을 비활성화하면 데이터베이스 락이 길게 유지될 수 있으므로, 트랜잭션을 가능한 짧게 유지해야 함.

요약

  • 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()을 호출하지 않아도 됩니다.

장점

  1. 간단한 작업 처리:

    • 각 명령이 독립적인 작업일 경우 사용하기 적합.
    • 트랜잭션 관리 코드를 작성할 필요가 없어 코드가 간단.
  2. 성능:

    • 짧은 작업에서 성능이 더 빠를 수 있음. 트랜잭션이 길게 유지되지 않아 락(Lock)이 짧게 걸립니다.
  3. 안전성:

    • 개발자가 commit() 또는 rollback()을 누락하는 실수를 방지.

적합한 경우

  1. 단순 작업:

    • 독립적인 INSERT, UPDATE, DELETE 또는 SELECT 작업.
    • 예: 로그 데이터 삽입, 단순한 데이터 업데이트.
      conn.setAutoCommit(true);
      Statement stmt = conn.createStatement();
      stmt.executeUpdate("INSERT INTO logs (message) VALUES ('System started');");
  2. 읽기 전용 작업:

    • SELECT 쿼리만 실행하는 경우 트랜잭션이 필요 없으므로 자동 커밋이 적합.
  3. 단독 사용자 환경:

    • 데이터 충돌 가능성이 없는 단일 사용자 애플리케이션.

2. setAutoCommit(false)

특징

  • SQL 명령이 자동으로 커밋되지 않음.
  • 트랜잭션이 끝날 때 개발자가 명시적으로 commit() 또는 rollback()을 호출해야 함.

장점

  1. 트랜잭션 단위 관리:

    • 여러 작업을 하나의 트랜잭션으로 묶어 처리할 수 있어 데이터 일관성을 유지.
  2. 부분 실패 처리 가능:

    • 작업 중 일부가 실패해도 롤백하여 데이터베이스 상태를 원래대로 복구 가능.
  3. 복잡한 비즈니스 로직 처리:

    • 여러 작업을 순서대로 수행하고, 조건에 따라 롤백 또는 커밋할 수 있음.

적합한 경우

  1. 복잡한 트랜잭션:

    • 여러 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(); // 작업 실패 시
      }
  2. 데이터 일관성이 중요한 경우:

    • 여러 작업이 반드시 하나의 단위로 실행되어야 할 때.
    • 예: 주문 생성과 재고 감소 작업.
  3. 동시성 제어:

    • 여러 사용자가 동시에 데이터를 변경할 가능성이 높은 환경에서 사용.
    • 트랜잭션이 완료될 때까지 다른 사용자가 수정할 수 없도록 보장.

3. setAutoCommit(true) vs setAutoCommit(false) 비교

특징 setAutoCommit(true) setAutoCommit(false)
커밋 시점 SQL 명령 실행 직후 자동 커밋. 명시적으로 commit() 또는 rollback() 호출 필요.
사용 난이도 간단. 추가적인 트랜잭션 관리 코드가 필요 없음. 개발자가 직접 트랜잭션을 관리해야 하므로 복잡.
데이터 일관성 관리 여러 작업이 논리적으로 연결되어 있지 않을 경우 적합. 여러 작업을 하나의 트랜잭션으로 묶어 데이터 일관성을 보장.
롤백 가능 여부 실패 시 개별 SQL 명령에 대해 롤백 불가. 실패 시 트랜잭션 전체를 롤백 가능.
적합한 작업 유형 단순한 INSERT, UPDATE, DELETE, SELECT. 복잡한 트랜잭션 처리(예: 계좌 이체, 주문 생성 등).
성능 짧고 단순한 작업에서는 더 빠름. 긴 트랜잭션 작업에서 성능 저하 가능(락 유지).
락(Lock) SQL 명령 실행 후 즉시 해제. 트랜잭션이 종료될 때까지 유지 가능.

4. 결론

  1. setAutoCommit(true)를 사용하는 경우:

    • SQL 명령이 독립적이고 간단하며, 트랜잭션의 복잡한 관리가 필요 없는 상황.
    • 예: 단순 데이터 로깅, 사용자 정보 업데이트.
  2. setAutoCommit(false)를 사용하는 경우:

    • 여러 작업을 하나의 논리적 단위로 묶어야 하거나, 데이터 일관성과 무결성이 중요한 경우.
    • 예: 계좌 이체, 주문 생성, 다중 테이블 조작.

둘 중 무엇을 사용할지는 애플리케이션의 요구사항(복잡도, 데이터 일관성, 성능 요구사항)에 따라 결정해야 합니다.