자치 트랜젝션의 정의

  • 트랜젝션내부에서 부모 트랜젝션으로부터 독립적인 새로운 트랜젝션


SQL> /*급여를 변경했을 경우 해당 부서 평균 급여액보다 부서 최고급여자의 1/2금액이 많을 경우 에러를
발생*/

롤백이 완료되었습니다.

SQL> create or replace procedure sal_check( p_deptno in number)
  2  is
  3    avg_sal number;
  4    max_sal number;
  5  begin
  6    select avg(sal), max(sal)
  7      into avg_sal, max_sal
  8      from emp
  9     where deptno = p_deptno;
 10
 11    if ( max_sal/2 > avg_sal ) then
 12      raise_application_error(-20001, 'Rule violated');
 13    end if;
 14
 15  end;
 16  /

프로시저가 생성되었습니다.

SQL>
SQL> create or replace trigger sal_trigger
  2  after insert or update or delete on emp
  3  for each row
  4  begin
  5    if ( inserting or updating ) then
  6      sal_check(:new.deptno);
  7    end if;
  8
  9    if ( updating or deleting ) then
 10      sal_check(:new.deptno);
 11    end if;
 12  end;
 13  /

트리거가 생성되었습니다.

SQL>
SQL>
SQL> update emp set sal = sal*1.1;
update emp set sal = sal*1.1
       *
1행에 오류:
ORA-04091: 테이블 SCOTT.EMP가 변화하고 있어서 트리거/함수가 이를 볼 수 없습니다
ORA-06512: "SCOTT.SAL_CHECK", 줄 6에서
ORA-06512: "SCOTT.SAL_TRIGGER", 줄 3에서
ORA-04088: 트리거 'SCOTT.SAL_TRIGGER'의 수행시 오류


SQL>
SQL>
SQL> create or replace procedure sal_check( p_deptno in number)
  2  is
  3    pragma autonomous_transaction; --자치 트랜젝션을 선언
  4    avg_sal number;
  5    max_sal number;
  6  begin
  7    select avg(sal), max(sal)
  8      into avg_sal, max_sal
  9      from emp
 10     where deptno = p_deptno;
 11
 12    if ( max_sal/2 > avg_sal ) then
 13      raise_application_error(-20001, 'Rule violated');
 14    end if;
 15
 16  end;
 17  /

프로시저가 생성되었습니다.

SQL>
SQL>
SQL> update emp set sal = sal*1.1;

14 행이 갱신되었습니다.

SQL>commit;


자치 트랜젝션이 적합한 경우

롤백이 불가능한 감사 기능 제공
  • 감사대상이 되는 특정 정보의 처리에 대해 실패하든 성공하든 모든 상황에 대한 기록을 해야하는 경우 사용할 수 있다.


그러나 쓰지 않는 것이 좋다 왜냐 자치트랜젝션은 문제가 많다
  • 실수하기 쉽고
  • 잘못된 방향으로 사용하면 성공하더라도 데이터 일관성이 깨지기 쉽다.
  • 자치 트랜잭션은 데이터 무결성에 영향을 끼칠 수 있다
  • 자치 트랜젝션의 잘못된 사용사례를 대부분 변경중 테이블 제약조건을 회피하려는 시도는 잘못되었다


그러면 뭘 써야되나?