데이터베이스 - 트랜잭션
트랜잭션(Transaction)과 잠금(Lock)의 이해
트랜잭션이란 = (업무, 함수, 프로세스)
1. 원자성(Aotomicity)
- 트랜잭션은 최소의 작업 단위로서 전체가 처리되거나 취소될 수 있지만 일부만 처리될
수 없다.
2. 일관성(Consistency)
- 트랜잭션이 실행된 이후 데이터베이스의 무결성은 반드시 유지돼야 한다.
3. 독립성(Isolation)
- 트랜잭션을 여러 개 동시에 실행하더라도 각각의 트랜잭션은 서로 영향을 줄 수 없다.
즉 실행이 종료되지 않은 트랜잭션의 결과는 다른 트랜잭션에서 참조하는 것이 불가능하다.
4. 영속성(Durability)
- 종료된 트랜잭션의 결과는 반드시 데이터베이스에 반영돼야 한다.
* 트랜잭션의 시작과 종료
①시작
- 이전 트랜잭션이 종료된 이후 DML(INSERT, UPDATE, DELETE)문장이나 DDL(CREATE, ALTER,
DROP, TRUNCATE), DCL(GRANT, REVOKE)문장에 실행됐을 때 시작된다.
②종료 - 보통 창을 끄는걸로 종료를 하는데 이게 정상종료인지 비정상종료 인지는 프로그램마다 다르다.
- COMMIT이나 ROLLBACK 명령이 실행 될 때 종료된다.
- DDL이나 DCL문장의 실행이 완료되면 자동으로 종료된다.
- 사용자의 정상 종료 시에 종료된다.
- 데드락(Deadlock)이 걸리면 트랜잭션의 일부만 종료된다.
과정
segment : 뭔가를 저장한다. / table도 세그먼트라고 할수있다.
undo segment : 롤백했을때를 대비해서 만들어진다.
1. undo segment가 5저장한다.
2. 5를 undo segment로 옮긴다.
3. update 7 (테이블정보를 수정하면 다른 DB와는 다르게 바로 저장함.)
4. 행 잠금 한다. / 행 잠금 = 독점 잠금 / 다른 사람들과 같은 db를 사용할때 행이
사라지면 안되기때문에 잠금한다.
5. 테이블을 잠금한다. / 테이블 잠금 = 공유 잠금 / 다른 사람들과 같은 db를 사용할때 테이블이
사라지면 안되기때문에 잠금한다.
* 독점 잠금(Exclusive lock)과 공유 잠금(Share lock)
독점 잠금은 현재 세션이외에는 접근을 불허하는 잠금이다. 이는 트랜잭션의 특징인 독립성을 보장하기
위한 것이다. 트랜잭션으로 행에 잠금이 발생하면 다른 세션에서는 해당 행을 검색할 수 없고 단지 언
두 세그먼트의 정보만 보게 된다. 그리고 이때 테이블에는 공유 잠금이 발생하는데 이것은 DML작업으
로 행이 잠겨있는 테이블에 대해서 DDL(DROP, ALTER)작업을 방지한다. 공유 잠금은 독점 잠금이 걸
린 행 이외 행에 대한 접근을 방해하지 않는다.
예제 1. 트랜잭션과 잠금의 이해
* 실습에는 두 개의 일반 사용자 세션이 사용된다.
- 동일한 st 계정으로 접속한 Sqlplus창을 두 개 실행한다.
- 두 개의 창은 [세션 1]과 [세션 2]로 구분한다.
[세션 1]
SQL> SELECT eno, ename, sal FROM emp
2 WHERE ename = '문시현';
ENO ENAME SAL
---- ---------- ----------
1001 문시현 4500
SQL> UPDATE emp SET sal = sal*2
2 WHERE ename = '문시현';
1 행이 갱신되었습니다.
SQL> SELECT eno, ename, sal FROM emp
2 WHERE ename = '문시현';
ENO ENAME SAL
---- ---------- ----------
1001 문시현 9000
[세션 2]
SQL> SELECT eno, ename, sal FROM emp
2 WHERE ename = '문시현';
ENO ENAME SAL
---- ---------- ----------
1001 문시현 4500
[세션 1]
SQL> COMMIT;
커밋이 완료되었습니다.
[세션 2]
SQL> SELECT eno, ename, sal FROM emp
2 WHERE ename = '문시현';
ENO ENAME SAL
---- ---------- ----------
1001 문시현 9000
예제 2. 트랜잭션에 의한 대기 현상 확인
* 환경은 [예제 1]과 동일하다.
1 행이 갱신되었습니다.
SQL> SELECT eno, ename, sal FROM emp
2 WHERE ename = '문시현';
ENO ENAME SAL
---- ---------- ----------
1001 문시현 9000
[세션 1]
SQL> SELECT eno, ename, sal FROM emp
2 WHERE ename = '안영희';
ENO ENAME SAL
---- ------- --------
0001 안영희 4800
SQL> UPDATE emp SET sal = sal * 1.5
2 WHERE ename = '안영희';
1 행이 갱신되었습니다.
SQL> SELECT eno, ename, sal FROM emp
2 WHERE ename = '안영희';
ENO ENAME SAL
---- ------- --------
0001 안영희 7200
[세션 2]
SQL> SELECT eno, ename, sal FROM emp
2 WHERE ename = '안영희';
ENO ENAME SAL
---- ------- --------
0001 안영희 4800
SQL> UPDATE emp SET comm = 900
2 WHERE ename = '안영희';
[세션 1]
SQL> COMMIT;
커밋이 완료되었습니다.
SQL> SELECT eno, ename, sal, comm FROM emp
2 WHERE ename = '안영희';
ENO ENAME SAL COMM
---- ---------- ---------- ----------
0001 안영희 7200 0
[세션 2]
SQL> UPDATE emp SET comm = 900
2 WHERE ename = '안영희';
1 행이 갱신되었습니다.
SQL> COMMIT;
커밋이 완료되었습니다.
[세션 1]
SQL> SELECT eno, ename, sal, comm FROM emp
2 WHERE ename = '안영희';
ENO ENAME SAL COMM
---- ---------- ---------- ----------
0001 안영희 7200 900
예제 3. 데드락(Dead Lock)을 발생하고 RDBMS의 처리 과정을 확인한다.
* 환경은 [실습 1]과 동일하다.
* [세션 1]과 [세션 2]는 각각 서로 다른 행에 독점 잠금을 걸고 서로 상대 트랜잭션이
독점 잠금을 걸어둔 행에 DML을 실행해 본다.
[세션 1]
SQL> SELECT eno, ename, dno FROM emp
2 WHERE ename IN ('안영희','문시현');
ENO ENAME DNO
---- ---------- ---
0001 안영희 01
1001 문시현 10
SQL> UPDATE emp SET dno = '02' WHERE ename = '안영희';
1 행이 갱신되었습니다.
SQL> SELECT eno, ename, dno FROM emp
2 WHERE ename IN ('안영희','문시현');
ENO ENAME DNO
---- ---------- ---
0001 안영희 02 ← 독점 잠금
1001 문시현 10
[세션 2]
SQL> SELECT eno, ename, dno FROM emp
2 WHERE ename IN ('안영희','문시현');
ENO ENAME DNO
---- ---------- ---
0001 안영희 01
1001 문시현 10
0SQL> UPDATE emp SET dno = '20' 2 WHERE ename = '문시현';
1 행이 갱신되었습니다.
SQL> SELECT eno, ename, dno FROM emp
2 WHERE ename IN ('안영희','문시현');
ENO ENAME DNO
---- ---------- ---
0001 안영희 01
1001 문시현 20 ← 독점 잠금
SQL> UPDATE emp SET sal = sal * 1.5
3 WHERE ename = '안영희';
[세션 1]
SQL> UPDATE emp SET sal = sal * 1.5
3 WHERE ename = '문시현';
[세션 2]
SQL> UPDATE emp SET sal = sal * 1.5
3 WHERE ename = '안영희';
UPDATE emp SET sal = sal * 1.5
*
1행에 오류:
ORA-00060: 자원 대기중 교착 상태가 검출되었습니다.
문제) 세션1, 2 둘다 독점잠금상태에서 세션2에서 먼저 update를 하고
세션1이 나중에 update를 했다. 근데 나중에 update한 세션1이 아니라
먼저한 세션2에서 교착상태가 검출되면서 해제되었다.
오라클의 데드락 해소 방식에 대해서 기술하고 이렇게 해소하는 이유는 무엇인가 논술하세요