자치 트랜젝션의 정의
- 트랜젝션내부에서 부모 트랜젝션으로부터 독립적인 새로운 트랜젝션
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;
자치 트랜젝션이 적합한 경우
롤백이 불가능한 감사 기능 제공
- 감사대상이 되는 특정 정보의 처리에 대해 실패하든 성공하든 모든 상황에 대한 기록을 해야하는 경우 사용할 수 있다.
그러나 쓰지 않는 것이 좋다 왜냐 자치트랜젝션은 문제가 많다
- 실수하기 쉽고
- 잘못된 방향으로 사용하면 성공하더라도 데이터 일관성이 깨지기 쉽다.
- 자치 트랜잭션은 데이터 무결성에 영향을 끼칠 수 있다
- 자치 트랜젝션의 잘못된 사용사례를 대부분 변경중 테이블 제약조건을 회피하려는 시도는 잘못되었다
그러면 뭘 써야되나?