Oracle
15. Chapter10 Transaction Control(20081031)
Gungume
2009. 1. 9. 10:49
Transaction (P10-2)
- 연관되는 연속적인 작업이 있을 때 모든 작업이 끝나던지, 중간에 문제가 생긴다면 완전 처음으로 되돌아가도록 해야함 -> 트랜잭션으로 묶으면 DB에서 알아서 해줌~
- Oracle에서는 SQLPLUS를 시작하면 트랜잭션이 자동으로 시작됨
- COMMIT, ROLLBACK을 사용하면 명시적으로 트랜잭션이 종료됨
COMMIT : 트랜잭션 시작 이후에 모든 정보 DB에 저장
ROLLBACK : 트랜잭션 시작 이후에 모든 정보 취소
- SQLPLUS에서 EXIT로 종료를 하면 COMMIT을 하고 종료되고 그냥 프로그램을 종료하면 ROLLBACK을 하고 종료된다.
- DML은 자동으로 트랙잭션 시작, DDL, DCL은 자동 COMMIT로서 ROLLBACK 안됨.
- COMMIT & ROLLBACK 예제
- SQL> DELETE FROM emp;
- 15 rows deleted.
- SQL> DELETE FROM dept;
- 6 rows deleted.
- SQL> ROLLBACK;
- Rollback complete.
- SQL> SELECT count(*) FROM emp;
- COUNT(*)
----------
15 - SQL> SELECT count(*) FROM dept;
- COUNT(*)
----------
6
- DDL 사용으로 인한 COMMIT
- SQL> SELECT * FROM dept;
- DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 Local Branck Korea
60 HQs - 6 rows selected.
- SQL> DELETE FROM dept
2 WHERE deptno=60; - 1 row deleted.
- // CREATE 문을 사용해서 이 시점에서 COMMIT이 일어남
- SQL> CREATE TABLE t (id number);
- Table created.
- SQL> ROLLBACK;
- Rollback complete.
- // ROLLBACK을 했지만 CREATE에서 COMMIT이 일어나서 ROLLBACK이 안됨
- SQL> SELECT * FROM dept;
- DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 Local Branck Korea
Tracsaction Control Statements (P10-5)
- SAVEPOINT x : x 위치에 롤백 시점 지정
- ROLLBACK TO SAVEPOINT x : x위치까지만 롤백 시킴, 트랜잭션이 종료되지는 않고 트랙잭션 시작위치는 그대로고 계속 진행됨.
- P10-6 예제
- SQL> SELECT deptno FROM emp WHERE empno=7788;
- DEPTNO
----------
20 - SQL> UPDATE emp SET deptno=30 WHERE empno=7788;
- 1 row updated.
- SQL> SAVEPOINT a;
- Savepoint created.
- SQL> DELETE FROM emp;
- 15 rows deleted.
- SQL> ROLLBACK TO a;
- Rollback complete.
- // SAVEPOINT a까지만 롤백을 했기 때문에 UPDATE 이후 값으로 출력됨.
- SQL> SELECT deptno FROM emp WHERE empno=7788;
- DEPTNO
----------
30 - // 트랜잭션 시작된 시점으로 롤백
- SQL> ROLLBACK;
- Rollback complete.
- // UPDATE 전 값으로 롤백됨~
- SQL> SELECT deptno FROM emp WHERE empno=7788;
- DEPTNO
----------
20
State of the Data During Transaction (P10-7)
- SCOTT 계정으로 SQLPLUS를 2개 띄워서 각각 접속 (같은 아이디 다른 세션)
- SCOTT.A 계정으로 DML문을 사용하면 해당되는 레코드에 자동으로 LOCK이 걸림(COMMIT, ROLLBACK 되기전까지)
- SCOTT.B 계정의 락이 걸린 데이터를 변경 등 하려고하면 대기하고 있다가 SCOTT.A에서 LOCK을 풀면 그때서야 수행됨.
- SCOTT.A 계정에서 데이터를 변경하면 SCOTT.B에서 SELECT 구문을 이용해서 조회하면 SCOTT.A가 변경한 데이터는 안보이고 예전 데이터가 조회됨
- SCOTT.A
- SQL> UPDATE emp
2 SET sal=0
3 WHERE deptno=10; - 3 rows updated.
- SQL> ROLLBACK;
- Rollback complete.
- SQL> UPDATE emp
2 SET sal=0
3 WHERE deptno=10; - 3 rows updated.
- SQL> SELECT sal FROM emp WHERE deptno=10;
- SAL
----------
0
0
0
- SCOTT.B
- SQL> SELECT sal
2 FROM emp
3 WHERE deptno=10; - SAL
----------
2450
5000
1300 - SQL> UPDATE emp
2 SET sal=5
3 WHERE deptno=10; - 3 rows updated. // SCOTT.A에서 롤백 등 해야 수행됨
- SQL> ROLLBACK;
- Rollback complete.
- SQL> SELECT sal FROM emp WHERE deptno=10; // SCOTT.A에서 sal=0으로 변경했지만 안보임~
- SAL
----------
2450
5000
1300
State of Data After Transaction (P10-8)
SESSION #1
- SQL> SELECT * FROM tr1;
SELECT * FROM tr1
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> /- no rows selected
- SQL> /
- no rows selected
- SQL> /
- A
----------
10 - SQL> UPDATE tr1 SET a=20;
- 1 row updated.
- SQL> SELECT * FROM tr1;
- A
----------
20 - SQL> COMMIT;
- Commit complete.
- SQL> SELECT * FROM tr1;
- A
----------
20 - SQL> /
- A
----------
20 - SQL> /
- A
----------
30
SESSION #2
- SQL> CREATE TABLE tr1 (a number);
- Table created.
- SQL> INSERT INTO tr1 VALUES(10);
- 1 row created.
- SQL> SELECT * FROM tr1;
- A
----------
10 - SQL> COMMIT;
- Commit complete.
- SQL> SELECT * FROM tr1;
- A
----------
10 - SQL> UPDATE tr1 SET a=30;
- 1 row updated.
- SQL> SELECT * FROM tr1;
- A
----------
30 - SQL> COMMIT;
- Commit complete.
Set Transaction (P10-10)
- 읽기 일관성 : 한번 읽었던 것은 다른곳에서 내용이 변경되도 내가 변경안한거면 처음 내용 그대로 읽어지는것
- READ ONLY : 읽기전용
SESSION 1
- (1)SQL> SET TRANSACTION READ ONLY; // 읽기 일관성 제공
- Transaction set.
- (2)SQL> SELECT sal FROM emp WHERE deptno=20;
- SAL
----------
800
2975
3000
1100
3000 - // SESSION2에서 (3), (4) 수행한 결과가 안보임(READ ONLY)
- (5)SQL> SELECT sal FROM emp WHERE deptno=20;
- SAL
----------
800
2975
3000
1100
3000
SESSION 2
- (3)SQL> UPDATE emp
2 SET sal=2000
3 WHERE deptno=20; - 5 rows updated.
- (4)SQL> COMMIT;
- Commit complete.
READ WRITE(기본값) :
SERIALIZABLE :
읽기 일관성 제공됨((P10-11 표 예제) 1~6번까지가 해당되는 내용)
자기 세션기준으로 초기값 그대로라면 수정가능(?) (다른 세션에 수정안하거나, commit 안한경우??)
READ COMMITTED(기본값) :
읽기 일관성 제공안함 -> 다른 세션에서 COMMIT하면 변경된 내용 보임
한 세션에서 DML문장을 사용하는 경우 LOCK이 걸리고 다른 세션에서는 LOCK이 걸린 항목을 변경하려면 변경안되고 기다리고 있음(LOCK을 건 세션에서 COMMIT 등을 하기전까지~)
이 글은 스프링노트에서 작성되었습니다.