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();}
}
}
}