A table ORIGINAL exists with the following structure:
ID VARCHAR Length 10 (key)
VALUE VARCHAR Length 10 (non-key)
A table REPLICATION exists with the following structure:
ID VARCHAR Length 10 (key)
CHANGE_TIMESTAMP NUMBER Length 15 (non-key)
I want to log every changed primary key to the REPLICATION table, with the latest change time stamp.
Therefore I have created this trigger in oracle:
CREATE OR REPLACE TRIGGER REPLICATION_TEST
AFTER INSERT OR UPDATE ON ORIGINAL
FOR EACH ROW
DECLARE timestamp DEC(15);
BEGIN
SELECT TO_NUMBER(TO_CHAR(SYSDATE, 'yyyymmddhh24miss'))
INTO timestamp
FROM dual;
INSERT INTO REPLICATION
FIELDS ("id", "change_timestamp")
VALUES (:NEW."id", timestamp);
EXCEPTION WHEN dup_val_on_index THEN
UPDATE REPLICATION
SET "change_timestamp" = timestamp
WHERE "id" = :NEW."id"
END;
Functionally, this works just fine. But in a productive environment with multiple sessions where arbitrary data changes can happen at any time, this infrequently leads to deadlocks. Presumably because of the UPDATE statement.
An alternative approach would be to add the CHANGE_TIMESTAMP field as additional key field to do only INSERTS into the REPLICATION table and skip the UPDATE in case of duplicates. This would work functionally just fine, but would obviously result in much more data being produced which I'd like to avoid.
What else can I do?