2016-11-13 56 views
0

我有以下觸發PL/SQL爲什麼我會觸發DEADLOCK動作?

CREATE OR REPLACE TRIGGER LAST_EDIT 
    BEFORE UPDATE ON MESSAGES 
    FOR EACH ROW 
    DECLARE 
    pragma autonomous_transaction; 
    BEGIN 
    if :NEW.TEXT <> :OLD.TEXT THEN 
     UPDATE MESSAGES set MESSAGES.LAST_EDITED=(select USERS.EMAIL from USERS inner join LAST_EDITED_TABLE on users.ID=LAST_EDITED_TABLE.USER_ID where 
     LAST_EDITED_TABLE.MESSAGE_ID=(select MESSAGE_ID from LAST_EDITED_TABLE where DATE_MESSAGE=(select max(DATE_MESSAGE) from LAST_EDITED_TABLE))); 
    ENDIF; 
COMMIT; 
END; 

而且我得到以下錯誤

ORA-06512: at "DIP.MESSAGEPACKAGE", line 35 
00060. 00000 - "deadlock detected while waiting for resource" 
*Cause: Transactions deadlocked one another while waiting for resources. 
*Action: Look at the trace file to see the transactions and resources 
      involved. Retry if necessary 

我試圖更新它說誰做的最後一次更新(從同一個表中的一行)的行。誰能幫幫我嗎?

+0

該觸發器基於表消息。如果此表上的更新正在完成,則觸發器將觸發。但觸發器想要在同一個表中執行更新,但該表仍被第一次更新鎖定。 – wieseman

+0

我想你必須在MESSAGE表上使用after語句觸發器。在使用更新觸發器之前,必須填寫plsql表,並在after語句觸發器中讀取plsql表的記錄,然後執行必須執行的操作。在這種情況下,它將會無限循環。 ==>一個更新會遇到另一個更新會遇到另一個更新.... – wieseman

+0

您的設計可能太複雜了。爲什麼不簡單地要求更新器也將正確的值更新爲'messages.last_edited_by_user'? – user272735

回答

1

難道你真的需要這個嗎?

CREATE OR REPLACE TRIGGER LAST_EDIT 
BEFORE UPDATE ON MESSAGES 
FOR EACH ROW 
DECLARE 
    email USERS.EMAIL%type; 
BEGIN  
if :NEW.TEXT <> :OLD.TEXT THEN 
    select USERS.EMAIL into email 
    from USERS inner join LAST_EDITED_TABLE on users.ID=LAST_EDITED_TABLE.USER_ID 
    where LAST_EDITED_TABLE.MESSAGE_ID = (select MESSAGE_ID from LAST_EDITED_TABLE where DATE_MESSAGE = (select max(DATE_MESSAGE) from LAST_EDITED_TABLE)); 
    :NEW.LAST_EDITED = email; 
END IF; 
COMMIT; 
END; 
/

在查詢,查找電子郵件還邏輯是太複雜了。當然,你可以簡化它。

相關問題