▶ 트랜잭션(Transaction)

: 업무 기본 단위, 반드시 한꺼번에 처리해야하는 단위 (데이터베이스)   (* 정보보안에서는 함수, 정보 등으로 해석 )


◾ 원자성(Aotomicity)
- 트랜잭션은 최소의 작업 단위로서 전체가 처리되거나 취소될 수 있지만 일부만 처리될
수 없다.
◾ 일관성(Consistency)
- 트랜잭션이 실행된 이후 데이터베이스의 무결성은 반드시 유지돼야 한다.
◾ 독립성(Isolation)  → Lock 과 관련
- 트랜잭션을 여러 개 동시에 실행하더라도 각각의 트랜잭션은 서로 영향을 줄 수 없다.
  즉 실행이 종료되지 않은 트랜잭션의 결과는 다른 트랜잭션에서 참조하는 것이 불가능하다.
◾ 영속성(Durability)
- 종료된 트랜잭션의 결과는 반드시 데이터베이스에 반영돼야 한다.

 

 

▶ 트랜잭션의 시작과 종료
①시작
- 이전 트랜잭션이 종료된 이후 DML(INSERT, UPDATE, DELETE)문장이나
DDL(CREATE, ALTER, DROP, TRUNCATE), DCL(GRANT, REVOKE)문장에 실행됐을 때 시작된다.

②종료
- COMMIT이나 ROLLBACK 명령이 실행 될 때 종료된다.
- DDL이나 DCL문장의 실행이 완료되면 자동으로 종료된다.
- 사용자의 정상 종료 시에 종료된다.
- 데드락(Deadlock)이 걸리면 트랜잭션의 일부만 종료된다.

 

 

▶ 트랜잭션 과정

 

▶ 독점 잠금(Exclusive lock)과 공유 잠금(Share lock)
독점 잠금은 현재 세션이외에는 접근을 불허하는 잠금이다. 이는 트랜잭션의 특징인 독립성을 보장하기
위한 것이다. 트랜잭션으로 행에 잠금이 발생하면 다른 세션에서는 해당 행을 검색할 수 없고 단지 언
두 세그먼트의 정보만 보게 된다. 그리고 이때 테이블에는 공유 잠금이 발생하는데 이것은 DML작업으
로 행이 잠겨있는 테이블에 대해서 DDL(DROP, ALTER)작업을 방지한다. 공유 잠금은 독점 잠금이 걸
린 행 이외 행에 대한 접근을 방해하지 않는다.

 

 

예제 1. 트랜잭션과 잠금의 이해
* 실습에는 두 개의 일반 사용자 세션이 사용된다.
- 동일한 st 계정으로 접속한 Sqlplus창을 두 개 실행한다.
- 두 개의 창은 [세션 1]과 [세션 2]로 구분한다.

 

[세션 1] commit 전 

SELECT eno, ename, sal FROM emp
WHERE ename = '문시현';

ENO     ENAME             SAL
------- ---------- ----------
1001    문시현           4500


UPDATE emp SET sal = sal*2
WHERE ename = '문시현';

1 행이 업데이트되었습니다.


SELECT eno, ename, sal FROM emp
WHERE ename = '문시현';

ENO     ENAME             SAL
------- ---------- ----------
1001    문시현           9000

 

[세션2] commit 전 

SELECT eno, ename, sal FROM emp
WHERE ename='문시현';

ENO     ENAME             SAL
------- ---------- ----------
1001    문시현           4500

 

[세션1] commit 후

COMMIT;

커밋이 완료되었습니다.

 

[세션2] commit 후

SELECT eno, ename, sal FROM emp
WHERE ename = '문시현';

ENO     ENAME             SAL
------- ---------- ----------
1001    문시현           9000

 

데이터를 읽는 것은 내가 select 문을 실행할 때 commit 된 데이터만 보는 것

 

 

예제 2. 트랜잭션에 의한 대기 현상 확인
* 환경은 [예제 1]과 동일하다.

[세션 1] commit 전 

SELECT eno, ename, sal FROM emp
WHERE ename = '안영희';

ENO     ENAME             SAL
------- ---------- ----------
0001    안영희           4800


UPDATE emp SET sal = sal * 1.5
WHERE ename = '안영희';

1 행이 업데이트되었습니다.


SELECT eno, ename, sal FROM emp
WHERE ename = '안영희';

ENO     ENAME             SAL
------- ---------- ----------
0001    안영희           7200

 

[세션 2] commit 전 

SELECT eno, ename, sal FROM emp
WHERE ename = '안영희';

ENO     ENAME             SAL
------- ---------- ----------
0001    안영희           4800


UPDATE emp SET comm = 900
WHERE ename = '안영희';

↑ 대기상태에 빠진다.

 

세션 1이 commit 가 되지 않아 대기상태에 빠진다.

 

[세션 1] commit 후

COMMIT;

커밋이 완료되었습니다.

SELECT eno, ename, sal, comm FROM emp
WHERE ename = '안영희';

ENO     ENAME             SAL       COMM
------- ---------- ---------- ----------
0001    안영희           7200          0

 

[세션 2] commit 후

UPDATE emp SET comm = 900
WHERE ename = '안영희';

1 행이 업데이트되었습니다.

COMMIT;

커밋이 완료되었습니다.

 

[세션 1] commit 후

SELECT eno, ename, sal, comm FROM emp
WHERE ename = '안영희';

ENO     ENAME             SAL       COMM
------- ---------- ---------- ----------
0001    안영희           7200        900

 

 

예제 3. 데드락(Dead Lock)을 발생하고 RDBMS의 처리 과정을 확인한다.
* 환경은 [실습 1]과 동일하다.
* [세션 1]과 [세션 2]는 각각 서로 다른 행에 독점 잠금을 걸고 서로 상대 트랜잭션이 독점 잠금을 걸어둔 행에 DML을 실행해 본다.

 

[세션 1]

SELECT eno, ename, dno FROM emp
WHERE ename IN ('안영희','문시현');

ENO     ENAME      DNO
------- ---------- -------
0001    안영희     01
1001    문시현     10


UPDATE emp SET dno = '02'
WHERE ename = '안영희';

1 행이 업데이트되었습니다.


SELECT eno, ename, dno FROM emp
WHERE ename IN ('안영희','문시현');

ENO     ENAME      DNO
------- ---------- -------
0001    안영희     02     ←← 독점 잠금
1001    문시현     10

 

[세션 2]

SELECT eno, ename, dno FROM emp
WHERE ename IN ('안영희','문시현');

ENO     ENAME      DNO
------- ---------- -------
0001    안영희     01
1001    문시현     10

UPDATE emp SET dno = '20'
WHERE ename = '문시현';

1 행이 업데이트되었습니다.

SELECT eno, ename, dno FROM emp
WHERE ename IN ('안영희','문시현');

ENO     ENAME      DNO
------- ---------- -------
0001    안영희     01
1001    문시현     20    ←← 독점 잠금


UPDATE emp SET sal = sal * 1.5
WHERE ename = '안영희';

↑ 대기상태에 빠짐

 

[세션 1]

UPDATE emp SET sal = sal * 1.5
WHERE ename = '문시현';

↑ 대기상태에 빠짐

 

[세션 2]

UPDATE emp SET sal = sal * 1.5
WHERE ename = '안영희';

↑ 대기상태에 빠짐

 

[세션 1]

UPDATE emp SET sal = sal * 1.5
WHERE ename = '문시현';

↑ 대기상태에 빠짐
세션 2 에서 update 실행 후 아래와 같이 에러가 뜬다.

UPDATE emp SET sal = sal * 1.5
                     *
1행에 오류:
ORA-00060: 자원 대기중 교착 상태가 검출되었습니다

 

이럴 경우 commit를 하면 된다.

+ Recent posts