본문 바로가기

Java SE/JDBC Transaction 02

JDBC Transaction 02

2개의 SQL 문장을 한개의 Transaction으로 처리하는 예제

import java.sql.*;
/* emp 테이블의 SAL컬럼을 은행의 계좌 잔고로 가정하고
* WARD가 200을 SMITH에게 송금하는 경우를 예로 들었다.
* 그룹단위 트랜잭션을 적용했기 때문에 중간에  에러가 발생하면
* 모든 SQL문장이 취소되어 송금했지만 받지 못하는 경우는 없다.
*/
class  Transaction02 {
 public static void main(String[] args) {
  try{
   Class.forName("oracle.jdbc.OracleDriver");
  }catch(ClassNotFoundException e){e.printStackTrace();}

  String dbURL = "jdbc:oracle:thin:@localhost:1521:ORCL";
  Connection con = null;
  PreparedStatement pstmt = null;
  boolean b = true;
  try{
   con = DriverManager.getConnection(dbURL, "scott", "tiger");
   con.setAutoCommit(false);//그룹단위 트랜잭션 적용(commit()하는 부분까지))
   pstmt = con.prepareStatement("update emp set sal=? where ename=?");
   pstmt.setInt(1, 800);//200을 SMITH한테 송금하므로 -200해서 잔고 800으로 수정
   pstmt.setString(2, "WARD");
   pstmt.executeUpdate();
   System.out.println("WARD가 송금했음");

   if(b) throw new Exception("처리도중 에러!");

   pstmt.setInt(1, 1200);//200을 받았기 때문에 기존 1000에 200을 더해 수정
   pstmt.setString(2, "SMITH");
   pstmt.executeUpdate();
   System.out.println("SMITH가 받았음");
   con.commit(); //여기까지 한개의 작업단위로 처리됨

  }catch(Exception e){
   try{
    con.rollback(); // 트랜잭션 범위에 있는 모든 문장이 취소됨
    System.err.println("실행 중에 오류 발생, 계좌이체 취소됨");
   }catch(Exception se){se.printStackTrace();}
  }finally{
   try{
    con.setAutoCommit(true);//문장단위 트랜잭션으로 복귀
    if(pstmt!=null)pstmt.close();
    if(con!=null)con.close();
   }catch(Exception e) {e.printStackTrace();}
  }
 }
}