Title |
[ORACLE] UPDATE 무결성 현상 | Product |
Plug-In |
---|---|---|---|
Phenomenon |
update 무결성 테스트시 세션2 에서 commit 한 결과가 반영이 안되는 현상이 발생
create table test6 (rlno varchar2(20) primary key, acno varchar2(20), cdno varchar2(20)) tablespace users; insert into test6 values ('980727-364783', '1', '2345-4323-2343-2343'); insert into test6 values ('980727-364784', '2', '2345-4323-2343-2343'); insert into test6 values ('980727-364785', '3', '2345-4323-2343-2343'); 세션1 update test6 set rlno = '123456-7891023' where acno = '1'; 세션2 update test6 set rlno = '789456-7891023' where acno = '1'; 세션1 commit; 세션2 commit; test11의 rlno의 값이 789456-7891023인지 세션1과 세션2에서 모두 확인 select * from test6 where acno='1'; |
||
Cause |
DB암호화 하면 pk 가 있기때문에 싱글view 로 만들게 됩니다.
이 상태에서는 다음과 같이 update 구문이 생기게 됩니다. DECLARE stmt LONG; V1 TEST6#.RLNO%TYPE :=XX1.ENC_VARCHAR2_INS(:OLD."RLNO",12,'ARIA192','TEST6','RLNO'); V2 TEST6#.ACNO%TYPE :=:OLD."ACNO"; V3 TEST6#.CDNO%TYPE :=:OLD."CDNO"; V4 TEST6#.RLNO%TYPE :=XX1.ENC_VARCHAR2_INS(:OLD."RLNO",12,'ARIA192','TEST6','RLNO'); BEGIN stmt:= 'UPDATE "SCOTT"."TEST6#" SET "RLNO"=:1,"ACNO"=:2,"CDNO"=:3 WHERE "RLNO"=:4'; 다음과 같이 trigger 의 조건절에 rlno 가 들어가있는 상태에서 다음을 실행하면 rlno 는 '980727-364783‘ 를 조건으로 '123456-7891023' 값을 update 합니다. 세션1 update test6 set rlno = '123456-7891023' where acno = '1‘; 그 상태에서 다음과 같이 같은 row 를 다른 값으로 update 하는 작업이 실행되지만 Oracle trigger 구조상 세션1에서 commit 을 하지 않았기때문에 세션1 에서 update 한 = '123456-7891023' 데이터가 아닌 ‘원본테이터 '980727-364783’ 데이터를 메모리에 기억하고 있습니다. (Oracle update 구조, 세션1 에서 commit 전까지 대기상태) 세션2 update test6 set rlno = '789456-7891023' where acno = '1'; 세션1 commit 을 하여 = '123456-7891023' 데이터가 정상 update 가 되었습니다. 세션2 의 대기상태가 풀립니다. 세션2 에서도 commit 을 하여 update 문을 실행하면 세션1에서 이미 데이터가 변경이 되었기때문에 메모리에 기억하고 있던 '980727-364783 데이터를 찾을수 없으므로 update 가 안되는 현상이 발생합니다. (오라클 내부적으로는 update 되었다고 나옴) 그러므로 최종 테이터는 세션1 에서 update 한 '123456-7891023' 데이터가 보이게 됩니다. |
||
Solution |
반면 rowid 를 사용하는 더블view 방식은 update 되는 컬럼이 아니기 때문에 있기 때문에 세션에 따라 같은 update 가 실행이 되더라도 마지막에 변경된 데이터를 확인 할 수 있습니다. (Oracle 내부 로직)
암호화 아닌 평문에서 같은 방식의 update 시에도 지금과 같은 결과가 발생하게 됩니다. (update 컬럼이 조건절에 비교가 되는 형식) |