트랜잭션(Transaction)
트랜잭션은 데이터 처리의 단위로 생각하면 됩니다.
오라클에서는 여러 SQL문을 하나의 논리적인 작업단위로 묶은 것을 의미합니다.
하나의 트랜잭션은 ALL-OR-Nothing 방식으로 처리됩니다.
* ALL-OR-Nothig 방식: 여러 SQL문들의 집합 모두가 정상 처리되면 정상 종료시키고,
하나의 SQL문이라도 오류가 있었다면 전체를 취소하는 방식
이러한 트랜잭션을 제어하는 명령어로는 다음과 같은 명령어가 있습니다.
COMMIT
아직 저장되지 않은 데이터를 데이터베이스(DB)에 저장하고 트랜잭션을 종료시키는 명령
ROLLBACK(TO SAVEPONT)
저장되지 않은 데어터들의 변경을 모두 취소하고 트랜잭션을 종료시키는 명령
이전의 COMMIT 상태 또는 지정된 SAVEPOINT로 복구시키는 명령어 입니다.
SAVEPOINT
현재까지의 트랜잭션을 특정 명칭으로 지정하여 임시저장해놓는 명령어입니다.
이제 SQL과 자바에서 어떻게 사용하는지 예시를 보여드리겠습니다.
1. SQL 예시
CUSTOMER 테이블
Column |
Data type |
NAME |
VARCHAR(100) |
AGE |
NUMBER |
ADDRESS |
VARCHAR(100) |
1.1 COMMIT
먼저, 커밋하는 예시입니다. 테이블이 비어있다고 가정하겠습니다.
현재 테이블 상태
NAME |
AGE |
ADDRESS |
|
|
|
INSERT INTO CUSTOMER (NAME, AGE, ADDRESS) VALUES('Hong', 15, 'Seoul'); COMMIT
CUSTOMER 테이블에 데이터를 INSERT하고 COMMIT하게 되면 트랜잭션을 종료시키고 데이터를 저장합니다.
COMMIT후 테이블
NAME |
AGE |
ADDRESS |
Hong |
15 |
Seoul |
INSERT한 데이터들이 커밋을 하였기 때문에 디비에 저장된 것을 볼 수 있습니다.
1.2 ROLLBACK
이번엔 rollback을 해보겠습니다.
테이블에 아무런 데이터가 저장되어 있지 않다고 가정해보겠습니다.
현재 테이블 상태
NAME |
AGE |
ADDRESS |
|
|
|
INSERT INTO CUSTOMER (NAME, AGE, ADDRESS) VALUES('Hong', 15, 'Seoul'); INSERT INTO CUSTOMER (NAME, AGE, ADDRESS) VALUES('Gil', 15, 'Busan'); ROLLBACK
ROLLBACK 후 테이블
NAME | AGE | ADDRESS |
|
|
|
데이터를 INSERT했지만 데이터베이스에 반영되지 않고 아무런 데이터가 없던 초기 상태로 복구됩니다. 이렇게 rollback은 해당 트랜잭션에 의해 변경된 데이터들을 다시 되돌려놓습니다.
1.3 SAVEPOINT
이번엔 중간에 savepoint를 지정하고 세이브포인트로 rollback해보겠습니다.
현태 테이블 상태
NAME | AGE | ADDRESS |
INSERT INTO CUSTOMER (NAME, AGE, ADDRESS) VALUES('Hong', 15, 'Seoul'); SAVEPOINT A; INSERT INTO CUSTOMER (NAME, AGE, ADDRESS) VALUES('Gil', 15, 'Busan'); ROLLBACK TO A
CUSTOMER 테이블에 데이터를 INSERT하고 중간에 SAVEPOINT를 지정해봤습니다. 이전에 롤백했을땐 처음 상태로 갔었죠?
하지만 ROLLBACK TO A 를 하게 되면 중간에 SAVEPOINT로 지정한 A까지만 ROLLBACK 됩니다.
ROLLBACK TO A 후 테이블
NAME | AGE | ADDRESS |
Hong | 15 | Seoul |
ROLLBACK 했을때와는 달리 ROLLBACK TO A 했을때의 테이블은 SAVEPOINT까지의 데이터가 저장되어있는 것을 볼 수 있습니다.
2. JDBC예시
이번엔 실제 자바를 사용해서 디비를 commit, rollback, rollback to savepoint 를 해보겠습니다.
2.1 commit, rollback
try { Connection conn = null; Statement stmt = null; conn = DriverManager.getConnection("jdbc:oracle:thin:@" + ip + ":" + port + ":" + sid, id, password); conn.setAutoCommit(false); stmt = conn.createStatement(); sql = "INSERT CUSTOMER (NAME, AGE, ADDRESS) VALUES('" + name +"'," + age + ",'" + address +"')"; Resultset rs = stmt.executeQuery(sql); if(rs != 0) conn.commit(); else conn.rollback(); stmt.close(); conn.close(); } catch(Exception e) { e.printStackTrace(); } finally { try { stmt.close(); conn.close(); } catch(Exception e) { log.info("Failed to stmt, connection close"); } }
디비에 접속하고 쿼리를 날리는 부분은 이전에 포스팅했던 글과 동일합니다.
2017/11/08 - [IT/Language] - JAVA - 오라클 DB에 쿼리 날리기( INSERT, DELETE, UPDATE)
먼저 처음엔 setAutoCommit이 true로 되어있기때문에 수동으로 commit, rollback을 하기 위해선 먼저 false로 바꿔줘야합니다.
conn.setAutoCommit(false);
이 부분만 조심하면 되겠네요.
자 이제 commit, rollback을 해보겠습니다.
COMMIT을 하고 싶다면
conn.commit();
ROLLBACK을 하고 싶다면
conn.rollback();
2.2 savepoint
이번엔 savepoint를 지정하고 해당 세이브포인트로 rollback 해보겠습니다.
try { Connection conn = null; Statement stmt = null; conn = DriverManager.getConnection("jdbc:oracle:thin:@" + ip + ":" + port + ":" + sid, id, password); conn.setAutoCommit(false); stmt = conn.createStatement(); sql = "INSERT CUSTOMER (NAME, AGE, ADDRESS) VALUES('" + name +"'," + age + ",'" + address +"')"; Savepoint savepoint = conn.setSavepoint("A"); Resultset rs = stmt.executeQuery(sql); if(rs != 0) conn.commit(); else conn.rollback(savepoint); stmt.close(); conn.close(); } catch(Exception e) { e.printStackTrace(); } finally { try { stmt.close(); conn.close(); } catch(Exception e) { log.info("Failed to stmt, connection close"); } }
이전 commit, rollback 할때와의 차이를 찾으셨나요 ?
line 12에 있는 코드가 savepoint를 지정하는 코드입니다.
Savepoint savepoint = conn.setSavepoint("A");
쿼리문을 날리다가 원하는 savepoint가 있으면 저 코드를 사용해서 지정해주시면 되겠습니다.
A라는 이름으로 세이브포인트가 지정됩니다.
이후 커밋을 하는 방법은 동일합니다. 다만 세이브포인트로 롤백하는 방법은 기존에 그냥 빈 괄호를 사용해서 롤백했다면 그 괄호에 어느 지점으로 돌아갈 것인지 세이브포인트를 넣어주면 됩니다.
conn.rollback(savepoint) 가 되겠습니다.
'IT > Language' 카테고리의 다른 글
오라클 쿼리문(INSERT, DELETE, UPDATE) 작성하는 법 (0) | 2017.12.08 |
---|---|
JAVA - 오라클 DB에 쿼리 날리기( INSERT, DELETE, UPDATE) (0) | 2017.12.07 |
Java DOM파서 3편 - "<"를 가진 xml파일 파싱하기(특수문자 치환) (0) | 2017.12.05 |
오라클 시퀀스(Sequence) 사용 및 .NEXTVAL 초기화 (0) | 2017.12.03 |
Java DOM파서 2편 - 특수문자가 있는 XML파싱하기 (0) | 2017.12.01 |