by-nc-sa     개발자, DBA가 함께 만들어가는 구루비 지식창고!

14S_트랜잭션 제어문장









트렌젝션






트렌젝션 개요




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

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

  • 트렌젝션의 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 블록 단위로는 영속성을 보장할 수 있다




문서정보

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.