2013-06-19 2 views
0

단일 트랜잭션에서 테이블에 대한 삽입 및 삭제 작업을 수행하고 있습니다.이 테이블에서 로그를 업데이트하는 트리거가 있습니다. 로그에는 항상 primaryId가있는 sequenceId가 있습니다 삽입시 증가합니다. 먼저 삭제하고 트랜잭션에 삽입합니다. 삽입에 대한 로그에오라클의 단일 트랜잭션에서 서로 다른 DML 쿼리에 대한 다른 타임 스탬프

  • 타임 스탬프와 동일한되고있는 삭제 :

    나는 두 가지 문제가 있습니다. 강제로 다른 수 있습니다.

  • 로그에서 작업 (삽입/삭제) 순서가 바뀌고 있습니다. 그것은 삽입 작업 (sequenceId에 따라) 이후에 오는 삭제 작업을 보여줍니다. 주문이 로그에서 일관성을 유지하려면 어떻게해야합니까 (삭제 후 삽입).

예 :

create table address (ID number, COUNTRY char(2)); 

create table address_log(SEQ_ID number, ID number, COUNTRY char(2), DML_TYPE char(1), CHANGE_DATE timestamp(6)); 

create sequence seq_id start with 1 increment by 100 nominvalue nomaxvalue cache 20 noorder; 

create or replace trigger trg_add 
before insert or delete on address 
FOR EACH ROW 
BEGIN 
if inserting then 
    insert into address_log values(SEQ_ID.nextval, :new.ID, :new.COUNTRY, 'I', sysdate); 
else 
    insert into address_log values(SEQ_ID.nextval, :old.ID, :old.COUNTRY, 'D', sysdate); 
end if; 
end; 

insert into address values(1,'US'); 
insert into address values(2,'CA'); 
delete from address where id = 1; 
insert into address values(3,'UK'); 
delete from address where id = 3; 

내가 단일 트랜잭션에서 마지막 DML 쿼리를 커밋 있다면, 내가 address_log에서 같은 순서를 볼 수 있습니다.

+0

@ wolφi 나는 그것을 결정하기 위해 로그의 기본 키 sequenceId를 사용한다. 항상 늘린다. 또한 질문을 업데이트했다. – rajsekhar

+0

코드 예제를 보내 주셔서 감사합니다. 그래서 두 문제는 @ Vincent의 대답으로 해결되었습니다. 그렇지 않습니까? (힌트 : 당신이 그것을 받아들이면, 빈센트와 몇 점을 얻을 것이다 ...) –

답변

3

타임 스탬프 열의 데이터 유형은 무엇입니까?

충분히 정밀도가 높은 TIMESTAMP을 사용하는 경우 순서를 유지해야합니다. 당신이 정말로 동시 이벤트 (예를 들어 동시 삽입을 구별하려는 경우, 어떤 경우

SQL> CREATE TABLE t_data (ID NUMBER, d VARCHAR2(30)); 

Table created 

SQL> CREATE TABLE t_log (ts TIMESTAMP (6), ID NUMBER, action VARCHAR2(1)); 

Table created 

SQL> CREATE OR REPLACE TRIGGER trg 
    2  BEFORE INSERT ON t_data 
    3  FOR EACH ROW 
    4 BEGIN 
    5  INSERT INTO t_log VALUES (systimestamp, :NEW.id, 'I'); 
    6 END; 
    7/

Trigger created 

SQL> INSERT INTO t_data (SELECT ROWNUM, 'x' FROM dual CONNECT BY LEVEL <= 10); 

10 rows inserted 

SQL> SELECT * FROM t_log ORDER BY ts; 

TS         ID ACTION 
----------------------------- ---------- ------ 
19/06/13 15:47:51,686192    1 I 
19/06/13 15:47:51,686481    2 I 
19/06/13 15:47:51,686595    3 I 
19/06/13 15:47:51,686699    4 I 
19/06/13 15:47:51,686800    5 I 
19/06/13 15:47:51,686901    6 I 
... 

: 기본 정밀도 - 예를 TIMESTAMP(6) (마이크로 초 정밀)에 대한

이 것

CREATE SEQUENCE log_sequence ORDER 

:), 당신은 항상 행이 정렬되도록 보장하기 위해 ORDER 키워드로, 추가 시퀀스를 사용할 수 있습니다 이벤트가 동시에 발생 했더라도 신뢰할 수있는 정렬 순서를 가질 수 있습니다.

+0

타임 스탬프의 데이터 타입은 TIMESTAMP (6)이다. 동일한 커밋에서 삽입 및 삭제가 발생하며 둘 다 동일한 타임 스탬프를 사용합니다. – rajsekhar

+0

@rajsekhar 나의 예제에서 볼 수 있듯이,'SYSTIMESTAMP'는 커밋시 결정되지 않고 삽입 중에 결정됩니다. 방아쇠가 항상 똑같은 초 단위로 실행되는 것은 거의 없습니다. 설명 된 동작을 재현하는 예제로 질문을 수정하십시오. create 문으로 트리거 코드, insert 문 및 select 문. –

+1

SYSTIMESTAMP 대신 SYSTIMESTAMP를 사용하면 차이가 있습니다. – rajsekhar