트랜잭션 관리(commit, rollback)
트랜잭션은 여러 SQL 문을 하나의 작업 단위로 묶어주는 것을 의미한다. commit은 트랜잭션을 완료하여 변경사항을 저장하고, rollback은 트랜잭션을 취소하여 변경사항을 되돌린다.
트랜잭션의 개념과 중요성
트랜잭션의 개념
- 트랜잭션(Transaction)은 데이터베이스에서 하나의 논리적인 작업 단위를 의미한다. 여러 SQL 문이 하나의 작업으로 묶여서 실행된다.
- 트랜잭션은 원자성(Atomicity), 일관성(Consistency), 고립성(Isolation), 지속성(Durability)의 특성을 갖는다. 이를 ACID 특성이라고 한다.
원자성 (Atomicity)
원자성은 트랜잭션의 모든 작업이 성공적으로 완료되거나, 전혀 실행되지 않은 상태를 보장힌다. 트랜잭션 내의 모든 작업이 성공하면 트랜잭션이 커밋되어 데이터베이스에 적용되고, 트랜잭션 중 하나라도 실패하면 트랜잭션이 롤백되어 모든 변경 사항이 취소된다. (마치 은행에서 이체 작업을 할 때, 돈이 출금되었지만 입금되지 않거나, 입금되었지만 출금되지 않는 상황이 없어야 한다는 의미이다. 둘 다 성공하거나 둘 다 실패해야 한다.)
일관성 (Consistency)
일관성은 트랜잭션이 실행되기 전과 후에 데이터베이스가 일관된 상태를 유지함을 보장한다.(은행에서 고객의 잔고가 음수가 되지 않도록 하는 규칙이 항상 지켜지는 것을 보장한다.)
고립성 (Isolation)
고립성은 동시에 실행되는 트랜잭션들이 서로 간섭하지 않도록 보장한다 . 하나의 트랜잭션이 완료되기 전까지는 다른 트랜잭션이 그 트랜잭션의 중간 결과를 볼 수 없다.(여러 사용자가 동시에 은행 계좌를 업데이트할 때, 각 사용자가 자신의 작업이 완료되기 전까지 다른 사용자의 업데이트를 볼 수 없다.)
두 개의 트랜잭션이 동시에 같은 데이터를 수정할 때, 각각의 트랜잭션은 고립되어 있어야 하며, 순서에 상관없이 같은 결과를 생성해야 보장한다.
지속성 (Durability)
지속성은 트랜잭션이 성공적으로 커밋된 후에는 시스템 장애가 발생하더라도 그 결과가 데이터베이스에 영구적으로 반영됨을 보장한다.(은행에서 이체가 완료된 후 시스템이 갑자기 중단되더라도, 이체된 금액이 손실되지 않고 그대로 유지되는 것을 보장한다.)
자동 커밋 모드와 수동 커밋 모드
자동 커밋 모드
- 기본적으로 JDBC는 자동 커밋 모드입니다. 각 SQL 문이 실행될 때마다 자동으로 커밋된다.
- 설정: connection.setAutoCommit(true);
수동 커밋 모드
- 수동 커밋 모드는 여러 SQL 문을 하나의 트랜잭션으로 묶어서 실행할 수 있다. 트랜잭션을 명시적으로 커밋하거나 롤백할 수 있다.
- 설정: connection.setAutoCommit(false);
- 커밋: connection.commit();
- 롤백: connection.rollback();
package ch04;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class TransactionExample {
public static void main(String[] args) {
// 드라이버 -> MySQL 개발자들이 자바 코드로 작성한 클래스의 묶음 (.jar)
// ver 8.0
String url = "jdbc:mysql://localhost:3306/m_board?serverTimezone=Asia/Seoul";
String id = "root";
String password = "asd123";
// 구현체를 사용하기 위해서
// 클래스 Class <-- 최상위 Object 안에 있음
// 동적 바인딩 처리
try {
// mysql 드라이버(구현클래스) 메모리에 로드
Class.forName("com.mysql.cj.jdbc.Driver");
//Connection conn = null;
// try catch resource 문법
try (Connection conn = DriverManager.getConnection(url, id, password)) {
conn.setAutoCommit(false); // 수동 커밋 모드 설정
String sqlInsert = " INSERT INTO user(username, password, email, userRole, address, createDate) "
+ " values( ? , ? , ?, ? , ? , now()) ";
PreparedStatement psmt1 = conn.prepareStatement(sqlInsert);
psmt1.setString(1, "김철수");
psmt1.setString(2, "asd123");
psmt1.setString(3, "a@nate.com");
psmt1.setString(4, "user");
psmt1.setString(5, "부산시진구");
psmt1.executeUpdate();
String sqlUpdate = "UPDATE user SET email = ? WHERE username = ?";
PreparedStatement psmt2 = conn.prepareStatement(sqlUpdate);
psmt2.setString(1, "b@naver.com");
psmt2.setString(2, "김유신");
psmt2.executeUpdate();
// 수동 커밋 모드를 설정했다면 직접 commit() 실행해야
// 물리적인 저장장치에 영구히 반영이 된다.
if(true) {
conn.commit();
} else {
conn.rollback();
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} // end of main
}
배치 처리
배치 처리(Batch Processing)는 데이터를 일괄적으로 모아서 한 번에 처리하는 방법을 말한다. 배치 처리는 대량의 데이터를 처리하거나 주기적으로 실행되는 작업을 자동화하는 데 사용된다. 일반적으로 대화형 사용자 입력 없이 실행되며, 백그라운드에서 작업이 수행된다.
- 배치 처리(Batch Processing)는 여러 SQL 문을 한 번에 실행하여 성능을 향상시키는 방법이다.
- 여러 SQL 문을 하나의 배치로 묶어서 데이터베이스에 전송하고 실행한다.
- Statement 및 PreparedStatement를 이용한 배치 처리가 존재한다.
특징
- 자동화: 주기적으로 실행되며, 인간의 개입 없이도 일정한 시간에 자동으로 수행됩니다.
- 대량 처리: 대량의 데이터를 한 번에 처리할 수 있습니다.
- 비실시간: 실시간으로 사용자와 상호작용하지 않고, 정해진 시간에 실행됩니다.
- 신뢰성: 정해진 규칙에 따라 안정적으로 데이터를 처리합니다.
사용 예시
- 급여 계산: 회사의 모든 직원에 대한 월급을 한 번에 계산하고 지급하는 작업.
- 데이터 마이그레이션: 한 시스템에서 다른 시스템으로 대량의 데이터를 이전하는 작업.
- 로그 분석: 서버 로그 파일을 모아서 주기적으로 분석하고 보고서를 생성하는 작업.
package ch05;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class BatchExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/demo3?serverTimezome=Asia/Seoul";
String user = "root";
String password = "asd123";
// 11.
Connection conn = null;
try {
// 1. MySQL 드라이브 로드
Class.forName("com.mysql.cj.jdbc.Driver");
// 2. 자바 표준 API
conn = DriverManager.getConnection(url, user, password);
// 3. 트랜잭션 처리
conn.setAutoCommit(false); // 수동 커밋으로 변경
// 4. 배치 처리 -> User 테이블에 한 번 사용자를 3명 넣어보자.
// 4.2
String sql = " INSERT INTO user(name, email) VALUES (?, ?) ";
// 4-1.
PreparedStatement pstmt = conn.prepareStatement(sql);
// 5. 1번 사용자 처리
pstmt.setString(1, "유저1");
pstmt.setString(2, "유저1@naver.com");
// 6.
// pstmt.executeUpdate();
// 배치 처리 하기 위해 호출할 메서드가 필요
pstmt.addBatch(); // <-
// 7. 2번 사용자 처리
pstmt.setString(1, "유저2");
pstmt.setString(2, "유저2@naver.com");
pstmt.addBatch(); // <-
// 8. 3번 사용자 처리
pstmt.setString(1, "유저3");
pstmt.setString(2, "유저3@naver.com");
pstmt.addBatch(); // <-
// 9.
int[] rowCounts = pstmt.executeBatch();
conn.commit(); // 물리적인 저장 장치에 영구히 반영하겠다.
System.out.println("배치처리 완료 : " + rowCounts.length);
} catch (Exception e) {
e.printStackTrace();
// 10. // 13. 트라이캐치
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
} finally {
try {
// 14.
// conn.close();
// 15.
if(conn != null) {
conn.close();
}
} catch (SQLException e1) {
e1.printStackTrace();
}
}
}
}// end of main
}// end of class
'Java' 카테고리의 다른 글
JDBC에서의 예외 처리 (1) | 2024.06.18 |
---|---|
JDBC 성능 최적화 (2) | 2024.06.18 |
래퍼 클래스 ( Wrapper Class ) (0) | 2024.06.12 |
JDBC 기본 사용법 (0) | 2024.06.11 |
JDBC 설치 및 설정 (0) | 2024.06.11 |