트렌젝션

트렌젝션 개요

  • 트렌젝션은 파일 시스템과 데이터베이스를 구분짓는 특징 중 하나이다.
  • 파일시스템은 쓰기 도중 운영체제가 갑자기 정지하면 훼손 가능성이 크다
  • 파일 두개가 동기화 된 상태를 유지하더라도 변경 작업 중 운영체제가 정지하면 두 개의 동기화가 깨질 수 있다


  • 트렌젝션은 일관된 상태에서 다음 일관된 상태로 데이터베이스를 전환한다. 일관성을 유지하는 것이 트렌젝션의 기능이다


  • 트렌젝션의 4가지 특성은 원자성/일관성/고립성/지속성이다


트렌젝션 제어

오라클 특성
  • 트렌젝션은 묵시적으로 데이터를 변경하는 첫 번 째 문장과 함께 시작한다
  • SET TRANSACTION / DBMS_TRANSACTION 으로 명시적으로 시작 가능하다
  • COMMIT/ROLLBACK 으로 종료 가능하다
  • 오라클의 트렌젝션 원자성 보호는 개별 문장에도 적용된다
  • 한 문장이 실패했다고 그 전에 수행 한 다른 문장이 롤백되지는 않는다


트렌젝션 제어 문장
COMMIT
  • COMMIT(COMMIT WORK) 로 사용 할 수 있다.
  • 주석으로 라벨을 붙여서 의심되는 분산 트렌젝션을 강제 커밋 할 수도 있으며
  • 비동기 커밋을 수행할 수도 있다


ROLLBACK
  • ROLLBACK(ROLLBACK WORK) 로 사용할 수 있다
  • 언두에서 변경 전 정보를 읽어 다시 되돌린다


SAVEPOINT
  • 트렌젝션 중간에 표시하여 부분 롤백을 가능하게 만들어 준다


ROLLBACK TO [ SAVEPOINT ]
  • SAVEPOINT 지정 한 부분까지 부분 롤백이 가능하다


SET TRANSACTION
  • 트렌젝션 고립 수준이나 속성을 설정할 수 있다
  • SET TRANSACTION READ ONLY; / SET TRANSACTION READ WRITE;


원자성

트리거의 경우
  • DML 문장에 트리거 설정 하였을 경우 DML 에 딸려있는 트리거도 문장의 일부분으로 간주한다.
  • DML 문장이 실패하면 트리거가 동작할지라도 그 이전 문장까지 롤백한다



SQL> create table t2 ( cnt int );

Table created.

SQL> insert into t2 values ( 0 );

1 row created.

SQL> commit;

Commit complete.

SQL> create table t ( x int check ( x>0 ) );

Table created.

SQL> create trigger t_trigger
before insert or delete on t for each row
begin
if ( inserting ) then
update t2 set cnt = cnt + 1;
else
update t2 set cnt = cnt - 1;
end if;
dbms_output.put_line('I fired and updated '||sql%rowcount||' rows');
end;
/

Trigger created.

SQL> set serveroutput on
SQL> insert into t values (1);
I fired and updated 1 rows

1 row created.

SQL> insert into t values(-1);
I fired and updated 1 rows
insert into t values(-1)
*
ERROR at line 1:
ORA-02290: check constraint (LIM.SYS_C0021582) violated

SQL> select * from t2;

       CNT
----------
         1

SQL> rollback;

Rollback complete.

SQL> select * from t2;

       CNT
----------
         0

SQL> select * from t;

no rows selected

SQL>


프로시저의 경우
  • PL/SQL 블록도 문장으로 간주한다
  • 아래와 같은 예제가 동작 하는 이유는 Procedure 내부에 자체적으로 Commit/Rollback 이 없기 때문이다



SQL> create or replace procedure p as
  2  begin
  3  insert into t values(1);
  4  insert into t values(-1);
  5  end;
  6  /

Procedure created.

SQL>
SQL> exec p;
I fired and updated 1 rows
I fired and updated 1 rows
begin
*
ERROR at line 1:
ORA-02290: check constraint (LIM.SYS_C0021582) violated
ORA-06512: at "LIM.P", line 4
ORA-06512: at line 2


SQL> select * from t2;

       CNT
----------
         0

SQL> select * from t;

no rows selected

SQL>


  • PL/SQL 블록에 익셉션 처리 할 경우는 경우가 달라진다



SQL> begin
  2  p;
  3  exception when others then
  4  dbms_output.put_line('Error : '||sqlerrm);
  5  end;
  6  /
I fired and updated 1 rows
I fired and updated 1 rows
Error : ORA-02290: check constraint (LIM.SYS_C0021582) violated

PL/SQL procedure successfully completed.

SQL> select * from t;

         X
----------
         1

SQL> select * from t2;

       CNT
----------
         1

SQL>


-------- 프로시저 안에 예외처리를 해도 마찬가지 ---------

SQL> create or replace procedure p as
begin
insert into t values(1);
insert into t values(-1);
exception when others then
dbms_output.put_line('Error : '||sqlerrm);
end;
/

Procedure created.

SQL> exec p;
I fired and updated 1 rows
I fired and updated 1 rows
Error : ORA-02290: check constraint (LIM.SYS_C0021582) violated

PL/SQL procedure successfully completed.

SQL> select * from t;

         X
----------
         1

SQL> select * from t2;

       CNT
----------
         1

SQL>



  • 이유는 예외처리로 인해 오류가 발생하면 PLSQL Block 을 롤백하는 기능이 수행되지 않았기 때문이다


DDL과 원자성
  • DDL 문장을 수행하면 그 전까지 진행 중이던 트렌젝션은 묵시적으로 COMMIT 된다
  • 이 후 DDL 이 성공하면 반영하고 실패하면 DDL 은 롤백한다
  • DDL 자체도 묵시적 COMMIT 으로 동작한다.


영속성

  • 트렌젝션이 커밋 되면 변경 데이터는 DBMS 에 영구적으로 반영한다
  • 다음과 같은 예외 사항이 있다


영속성의 예외(오라클)
  • COMMIT 문의 확장인 COMMIT WRITE NOWAIT 기능을 사용 할 경우
  • DB 링크를 사용하지 않고 비 분산 환경에서 PLSQL 코드 블록 내에서 커밋 하는 경우


COMMIT WRITE NOWAIT
  • 10gR2 이상부터 COMMIT 에 WRITE 를 붙일 우 있다
COMMIT WRITE WAIT 이 기본 값이다
  • 커밋 시 LGWR 프로세스가 리두 버퍼에서 온라인 리두로그에 기록한다


COMMIT WRITE NOWAIT 은 다음과 같이 동작한다
  • LGWR 프로세스가 리두 버퍼에서 온라인 리두로그에 기록하기 전에 커밋을 완료한다
  • 사용자에게 커밋 완료 상태를 보여주지만 실제로 파일에 쓰이지 않았기 때문에 영속성을 보장하기 어렵다
  • 로그 파일 기록으로 인한 물리적 I/O 시간을 줄이기 위한 목적으로 사용 가능하나 신중하게 사용하여야 한다.


  • COMMIT WRITE NOWAIT 은 사용자와 상호작용이 없는 백그라운드 Application 에서 사용할 수 있다
  • 실패 시 자동으로 재 시작할 수 있는 배치 프로그램(큐잉 매커니즘을 자체 구현한 프로그램) 등..
  • 책 363 페이지 업무 사례 참조


비 분산 환경에서 PL/SQL 블록 내부 커밋
  • 프로시저 내부에서 수행 하는 커밋은 NOWAIT 방식이다
  • 사용자에게 프로시저 수행 완료를 반환하기 전에 마지막 생성 REDO 를 온라인 리두에 기록한다
  • PL/SQL 블록 단위로는 영속성을 보장할 수 있다