2013-10-07 83 views
0

我有以下的觸發這確保只有一個記錄具有場DEFAULTCARD = 1DB2觸發超時

create trigger TRG_U_XSTRDCRD 
    after update on XSTOREDCARD referencing new as N old as O 
    for each row mode db2sql 
    begin atomic 
     if N.DEFAULTCARD = 1 then 
      update XSTOREDCARD 
       set DEFAULTCARD = 0 
       where USERS_ID = N.USERS_ID and ID <> N.ID; 
     end if; 
    [email protected] 

我還要確保只有一個記錄具有1的EBACTIVE字段的值,所以我試過這個。

create trigger TRG_U_XSTRDCRD 
    after update on XSTOREDCARD referencing new as N old as O 
    for each row mode db2sql 
    begin atomic 
     if N.DEFAULTCARD = 1 then 
      update XSTOREDCARD 
       set DEFAULTCARD = 0 
       where USERS_ID = N.USERS_ID and ID <> N.ID; 
     end if; 
     if N.EBACTIVE = 1 then 
      update XSTOREDCARD 
       set EBACTIVE = 0 
       where USERS_ID = N.USERS_ID and ID <> N.ID; 
     end if; 
    [email protected] 

但它沒有工作,它會導致在超時的更新幾分鐘後:

Caused by: com.ibm.db2.jcc.b.SqlException: DB2 SQL error: SQLCODE: -101, SQLSTATE: 54001, SQLERRMC: null 
at com.ibm.db2.jcc.b.zc.e(zc.java:1606) 
at com.ibm.db2.jcc.b.zc.a(zc.java:1206) 
at com.ibm.db2.jcc.a.db.h(db.java:149) 
at com.ibm.db2.jcc.a.db.a(db.java:43) 
at com.ibm.db2.jcc.a.r.a(r.java:30) 
at com.ibm.db2.jcc.a.sb.g(sb.java:152) 
at com.ibm.db2.jcc.b.zc.n(zc.java:1186) 
at com.ibm.db2.jcc.b.ad.db(ad.java:1761) 
at com.ibm.db2.jcc.b.ad.d(ad.java:2203) 
at com.ibm.db2.jcc.b.ad.V(ad.java:521) 
at com.ibm.db2.jcc.b.ad.executeUpdate(ad.java:504) 
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2595) 
... 19 more 

對什麼是錯或如何做到這一點有什麼建議?

乾杯! NFV

+0

請顯示確切的錯誤代碼和完整的信息。 – mustaccio

+0

SQLCODE -101不是超時;這意味着你正在達到內存限制或其他資源限制。既然你沒有提到你的DB2版本和平臺,我不能給你更多的細節。與您的DBA交談。 – mustaccio

+0

以下頁面可能會爲您提供一些提示。 http://www.dbforums.com/db2/978746-sql0954c-not-enough-storage-available-application-heap-process.html –

回答

0

看完this nice post之後,我可能已經意識到你對很多人做了一些更新。您定義了更新後同步表的更新後觸發器。您實際上更新了該用戶的所有行。假設您每個用戶有10行,並且一行更改了DEFAULTCARD標誌。這意味着您不管是否需要更新,都會更新9行。這聽起來不是什麼大問題,但是,如果你有5,000,000條記錄,那麼即使你只需要更新一條記錄(即舊的DEFAULTCARD記錄),你也可以更新4,999,999條記錄。

 update XSTOREDCARD 
      set DEFAULTCARD = 0 
      where USERS_ID = N.USERS_ID and DEFAULTCARD = 1 and ID <> N.ID; 

此聲明應該隻影響1或沒有記錄。因此,而不是運行4,999,999更新和觸發電話,你只有一個更新。

對於EBACTIVE也是如此。更好的是,如果EBACTIVE和DEFAULTCARD對於不同的記錄是1,那麼它會變得非常混亂,因爲更新到EBACTIVE會觸發更新到DEFAULTCARD,這將更新到EBACTIVE再次觸發。所以如果我沒有弄錯,你就陷入了無限循環。

begin atomic 
    if N.DEFAULTCARD = 1 then 
     update XSTOREDCARD 
      set DEFAULTCARD = 0 
      where USERS_ID = N.USERS_ID and DEFAULTCARD = 1 and ID <> N.ID; 
    end if; 
    if N.EBACTIVE = 1 then 
     update XSTOREDCARD 
      set EBACTIVE = 0 
      where USERS_ID = N.USERS_ID and EBACTIVE = 1 and ID <> N.ID; 
    end if; 
[email protected] 

這應該表現得更好。

編輯:秒嘗試

我是我們應該只更新一集,如果該值實際改變。

begin atomic 
    if N.DEFAULTCARD = 1 and O.DEFAULTCARD != 1 then 
     update XSTOREDCARD 
      set DEFAULTCARD = 0 
      where USERS_ID = N.USERS_ID and DEFAULTCARD = 1 and ID <> N.ID; 
    end if; 
    if N.EBACTIVE = 1 and O.EBACTIVE !=1 then 
     update XSTOREDCARD 
      set EBACTIVE = 0 
      where USERS_ID = N.USERS_ID and EBACTIVE = 1 and ID <> N.ID; 
    end if; 
[email protected] 
+0

感謝您的建議,它看起來像一個很好的,但我仍然得到相同的錯誤... – nfvindaloo

+0

你的桌子有多大? –

+0

只有大約10行! – nfvindaloo