2014-02-11 76 views
0

我想創建DB2 10.1.2當字段更新爲一定值時,在該表中的行數與該值,看看是否計數(在Linux上運行LUW)觸發它與另一個表中的計數相匹配,然後更新該表(例如,將任務狀態彙總爲工作狀態)。表達它似乎很簡單:DB2觸發行鎖定

CREATE TRIGGER AUTHORED 
    AFTER UPDATE OF TASK_STATUS ON TASK_TABLE 
    REFERENCING NEW AS N FOR EACH ROW WHEN (TASK_STATUS = 'Completed') 
    update JOB_TABLE set JOB_STATUS='Completed' 
     where JOB_TABLE.ID = N.JOB_ID 
     and JOB_TABLE.TOTAL_TASKS = (select count(*) from TASK_TABLE 
      where TASK_TABLE.JOB_ID = N.JOB_ID 
      and TASK_TABLE.TASK_STATUS = 'Completed') 

不幸的是,它似乎是觸發的情況下,觸發的身體是不是在同一個工作單位,當你指望從觸發鎖定了這一行發生死鎖更新自己。下面是「的db2pd -wlocks」輸出我做一個觸發更新後:

Locks being waited on : 
AppHandl [nod-index] TranHdl Lockname     Type  Mode Conv Sts CoorEDU AppName AuthID AppID 
44248 [000-44248] 111  0200040E070000000000000052 RowLock ..X  G 1385  perl  KJPIRES 10.0.15.139.38727.140201011731 
14937 [000-14937] 15   0200040E070000000000000052 RowLock .NS  W 1238  perl  KJPIRES 10.0.15.139.55287.140211231609 

我試圖用「與UR」的內部計數,但是當我創建觸發器(「SQL20159W將被明確地忽略由於語句上下文,隔離子句被忽略。SQLSTATE = 01652「)。

我也嘗試過使用BEFORE和INSTEAD OF,但遇到了問題。

這看起來好像是一件常見的事情。它通常如何處理?

+0

你有沒有嘗試'爲每個陳述'? – AngocA

+0

我剛剛嘗試過「對於每條語句」,它仍然僵持不下。 (我不確定如果更新更新多行並且我爲「每個語句」而不是「針對每一行」執行操作,但它無法正常工作會發生什麼情況。) – kjpires

+1

觸發器無法在就像你說的那樣,一個單獨的UOW,因爲觸發體實際上被編譯到引起觸發器運行的'UPDATE'語句的計劃中。你如何確定存在僵局? – mustaccio

回答

0

沒有什麼錯與上面的觸發器。我不知道,我的JOB_TABLE上的一個公開交易非常出色。我追查下來,做了回滾並完成了觸發更新。

我會用count(0)代替count(*)作爲建議的優化。

0

我不認爲這是僵局。首先,DB2有一個死鎖檢測器,如果有兩個連接在不同的資源上等待另一個資源的鎖,那麼DB2將會殺死其中的一個。我沒有看到兩個連接。

其次,你要更新另一個表(JOB_TABLE)的基礎上,從表所在的觸發器定義的值(COUNT)(TASK_TABLE)

CREATE TRIGGER AUTHORED 
AFTER UPDATE OF TASK_STATUS ON TASK_TABLE 
REFERENCING NEW AS N 
FOR EACH ROW WHEN (TASK_STATUS = 'Completed') 
    update JOB_TABLE 
    set JOB_STATUS='Completed' 
    where JOB_TABLE.ID = N.JOB_ID 
    and JOB_TABLE.TOTAL_TASKS = (  -- Total tasks before or after the update? 
    select count(*) 
    from TASK_TABLE 
    where TASK_TABLE.JOB_ID = N.JOB_ID 
    and TASK_TABLE.TASK_STATUS = 'Completed' 
    ) 

你有沒有運行更新的外觸發。它工作,不是嗎?

我認爲該交易修改是不是犯了行(更新task_table),當你發出選擇在觸發,等待對同一個表提交。事實上,事務並不知道被更新的行是否處於「已完成」狀態,並且您有一個謂詞來查找哪一個更新:JOB_TABLE.TOTAL_TASKS = x,但當前行可能是此集的一部分。

你打算更新哪一個?當前更新之前或當前更新之後的JOB_TABLE.TOTAL_TASKS?最後,我不確定爲什麼你有這個謂詞。

BTW,不要使用count(*),但數(0)

+0

_when在觸發器中發出select時 - - 不,它不。 – mustaccio

+0

另外,爲什麼_do不使用count(*)而是count(0)_? – mustaccio

+0

如果較低的優化級別,所有行都會被提取。 – AngocA