일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 스칼라 동시성
- play2 강좌
- play 강좌
- Actor
- 파이썬 머신러닝
- Adapter 패턴
- 하이브리드앱
- 파이썬
- 주키퍼
- 하이퍼레저 패브릭
- Hyperledger fabric gossip protocol
- 스칼라 강좌
- 파이썬 동시성
- CORDA
- 파이썬 데이터분석
- 플레이프레임워크
- 스위프트
- Play2 로 웹 개발
- 안드로이드 웹뷰
- 이더리움
- 파이썬 강좌
- Akka
- akka 강좌
- Golang
- 엔터프라이즈 블록체인
- 스칼라
- hyperledger fabric
- 블록체인
- Play2
- 그라파나
- Today
- Total
HAMA 블로그
JDBC 트랜잭션 본문
JDBC 기본 트랜잭션
JDBC API의 Connection 객체는 commit() 메소드와 rollback() 메소드를 제공한다.
기본적으로 Connection 객체에 setAutoCommit 이란 메소드가 있는데 기본값이 true 로 설정이 되어 있다.
하나의 쿼리당 자동시작~자동커밋이 일어난다는 이야기이다.
그러나 여러 개의 쿼리 문장이 하나의 작업으로 수행되어야 할경우에 각각의 문장이 자동으로 작동되지 못하게 해야한다.
오토커밋이 자동으로 작동되지 못하게 하려면 setAutoCommit(false); 로 지정해야 한다.
자 그럼 begin() 은 어딨느냐??
AutoCommit = true 일경우
암시적으로 각각의 액션시 (각각 SQL 문에서) 자동으로 BEGIN()
AutoCommit = false 일경우
이건 좀 희안하다. setAutoCommit(false) 를 호출하여 오토커밋코드를 꺼넣으면 시스템은 이 호출과 동시에 BEGIN 요청을 하게
된다. 이후의 commit() 과 rollback() 호출은 해당 SQL 을 호출한 뒤에 다시 BEGIN() 을 요청하게된다.
그 밖에 setAutoCommit 을 통해 모드를 바꾸면 동시에 commit() 1회 발생한다.
JDBC Savepoint
새로운 JDBC 3.0 Savepoint interface 는 추가적인 트랜잭션기능을 제공하는데 . Oracle's PL/SQL 같은 많은 현대 DBMS 에서는 그들의 환경내에 savepoints 를 지원하고있다. 당신이 세이프포인트를 세팅할때 트랜잭션안에 논리적 롤백 포인트를 정의할수있다.
만약 에러가 세이프포인트뒤에 발생하면 , 모든 변경사항 또는 세이브포인트 후에 만들어진 변화를 undo 를 하기위해 롤백메소드를 사용할수있다.
Connection 객체는 2가지 새로운 메소드로 세이브포인트를 요리할수있도록 도와준다.
setSavepoint(String savepointName): 새로운 세이브포인트를 정의하고 그 객체를 리턴받는다.
releaseSavepoint(Savepoint savepointName): 세이브포인트 삭제.
rollback (String savepointName) 는 특정 세이브포인트로 작업을 롤백한다.
다음 예를 통해 살펴보자.
try{ conn.setAutoCommit(false); Statement stmt = conn.createStatement(); // Savepoint 설정 Savepoint savepoint1 = conn.setSavepoint("Savepoint1"); String SQL = "INSERT INTO Employees " + "VALUES (106, 20, 'Rita', 'Tez')"; stmt.executeUpdate(SQL); String SQL = "INSERTED IN Employees " + "VALUES (107, 22, 'Sita', 'Tez')"; stmt.executeUpdate(SQL); conn.commit(); }catch(SQLException se){ conn.rollback(savepoint1); }
문제가 생기면 savepoint1 까지 롤백된다. insert 문은 작동안하겠지
좀더 구체적인 예를 살펴봅시다.
//STEP 1. 관련 패키지 임포트 import java.sql.*; public class JDBCExample { static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; static final String DB_URL = "jdbc:mysql://localhost/EMP"; static final String USER = "username"; static final String PASS = "password"; public static void main(String[] args) { Connection conn = null; Statement stmt = null; try{ //STEP 2: JDBC 드라이버 등록 Class.forName("com.mysql.jdbc.Driver"); //STEP 3: connection 맺고 System.out.println("Connecting to database..."); conn = DriverManager.getConnection(DB_URL,USER,PASS); //STEP 4: 오토 커밋 않하게함 conn.setAutoCommit(false); //STEP 5: statment 생성 System.out.println("Creating statement..."); stmt = conn.createStatement(); //STEP 6: 모든 데이터 가져오기 String sql = "SELECT id, first, last, age FROM Employees"; ResultSet rs = stmt.executeQuery(sql); System.out.println("List result set for reference...."); printRs(rs); // STEP 7: 세이브 포인트1 설정 Savepoint savepoint1 = conn.setSavepoint("ROWS_DELETED_1");
// STEP 8: ID = 110 삭제
System.out.println("Deleting row...."); String SQL = "DELETE FROM Employees WHERE ID = 110"; stmt.executeUpdate(SQL);
// 엇.. 잘못된 놈을 지웠네.. //STEP 8: Rollback the changes afetr save point 2. conn.rollback(savepoint1); // STEP 9: 세이브 포인트 2 설정 Savepoint savepoint2 = conn.setSavepoint("ROWS_DELETED_2");
System.out.println("Deleting row...."); SQL = "DELETE FROM Employees WHERE ID = 95"; stmt.executeUpdate(SQL); //STEP 10: Now list all the available records. sql = "SELECT id, first, last, age FROM Employees"; rs = stmt.executeQuery(sql); System.out.println("List result set for reference...."); printRs(rs); //STEP 10: Clean-up environment rs.close(); stmt.close(); conn.close(); }catch(SQLException se){ //Handle errors for JDBC se.printStackTrace(); // If there is an error then rollback the changes. System.out.println("Rolling back data here...."); try{ if(conn!=null) conn.rollback(); }catch(SQLException se2){ se2.printStackTrace(); }//end try }catch(Exception e){ //Handle errors for Class.forName e.printStackTrace(); }finally{ //finally block used to close resources try{ if(stmt!=null) stmt.close(); }catch(SQLException se2){ }// nothing we can do try{ if(conn!=null) conn.close(); }catch(SQLException se){ se.printStackTrace(); }//end finally try }//end try System.out.println("Goodbye!"); }//end main public static void printRs(ResultSet rs) throws SQLException{ //Ensure we start with first row rs.beforeFirst(); while(rs.next()){ //Retrieve by column name int id = rs.getInt("id"); int age = rs.getInt("age"); String first = rs.getString("first"); String last = rs.getString("last"); //Display values System.out.print("ID: " + id); System.out.print(", Age: " + age); System.out.print(", First: " + first); System.out.println(", Last: " + last); } System.out.println(); }//end printRs() }//end JDBCExample
다음처럼 컴파일하고
C:\>javac JDBCExample.java C:\>
JDBCExample 실행하면 다음과 같이 나오게된다.
C:\>java JDBCExample Connecting to database... Creating statement... List result set for reference.... ID: 95, Age: 20, First: Sima, Last: Chug ID: 100, Age: 18, First: Zara, Last: Ali ID: 101, Age: 25, First: Mahnaz, Last: Fatma ID: 102, Age: 30, First: Zaid, Last: Khan ID: 103, Age: 30, First: Sumit, Last: Mittal ID: 110, Age: 20, First: Sima, Last: Chug Deleting row.... Deleting row.... List result set for reference.... ID: 100, Age: 18, First: Zara, Last: Ali ID: 101, Age: 25, First: Mahnaz, Last: Fatma ID: 102, Age: 30, First: Zaid, Last: Khan ID: 103, Age: 30, First: Sumit, Last: Mittal ID: 110, Age: 20, First: Sima, Last: Chug Goodbye! C:\>
ORACLE Savepoint
펌 : http://reiphiel.tistory.com/entry/jdbc-transaction-savepoints
SQL예(오라클)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | INSERT INTO TEST_USER ( NAME ) VALUES ( 'JOHN' ); SAVEPOINT MARK; INSERT INTO TEST_USER ( NAME ) VALUES ( 'MARK' ); SAVEPOINT JACK; INSERT INTO TEST_USER ( NAME ) VALUES ( 'JACK' ); SAVEPOINT PAUL; INSERT INTO TEST_USER ( NAME ) VALUES ( 'PAUL' ); ROLLBACK TO JACK; INSERT INTO TEST_USER ( NAME ) VALUES ( 'JANE' ); COMMIT ; |
실행 결과
SQL문은 실행한 결과는 위와 같은데 SAVEPOINT로 특정 세이브포인트까지 롤백을 하게되면 롤백실행한
부분부터지정한 세이브 포인트까지 롤백 되는 것을 알수있다.
구조적으로 나중에 지정한 세이브포인트는 직전 세이브 포인트에 종속적이라고 보면 되겠다.
중첩된 트랜잭션이라고 보면 되겠다. 그리고 지정한 세이브포인트 이전과 롤백을 실행한 이후의 SQL에는
영향을 미치지 않았다는 것을 알 수 있다.
'RDBMS (PostgreSQL)' 카테고리의 다른 글
왜 PostgreSQL 을 선택 했나? ( PostgreSQL vs MySQL ) [번역] (0) | 2016.08.02 |
---|---|
[DB/분산] 초보자를 위한 CAP 이론 (1) | 2016.04.29 |
트랜잭션 인사이드 (0) | 2015.07.01 |
PostgreSQL 조인 (0) | 2015.05.13 |
Efficient Use of PostgreSQL Indexes (0) | 2015.05.13 |