데이터베이스

데이터베이스 - 트랜잭션

slcry 2022. 11. 3. 15:06

트랜잭션(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에서 교착상태가 검출되면서 해제되었다. 

 

오라클의 데드락 해소 방식에 대해서 기술하고 이렇게 해소하는 이유는 무엇인가 논술하세요