在資料庫中經常會遇到這樣的情況:一個主表a,一個子表b,b表中包含有a表的主鍵作為外鍵。當要插入資料的時候,我們會先插入a表,然後獲得a表的identity,再插入b表。如果要進行删除操作,那麼就先删除子表b,然後再删除主表a。在程式設計中,對兩個表的操作是在一個事務之中完成的。
當系統使用頻繁就會出現插入操作和删除操作同時進行的情況。這個時候插入事務會先将主表a放置獨占鎖,然後去通路子表b,而同時删除事務會對子表b放置獨占鎖,然後去通路主表a。插入事務會一直獨占着a表,等待通路b表,删除事務也一直獨占着b表等待通路a表,于是兩個事務互相獨占一個表,等待對方釋放資源,這樣就造成了死鎖。
遇到這種情況我聽說了三種做法:
1 取消ab兩個表之間的外鍵關系,這樣就可以在删除資料的時候就可以先删除主表a,然後删除子表b,讓對這兩個表操作的事務通路順序一緻。
2 删除a表資料之前,先使用一個事務将b表中相關外鍵指向另外a表中的另外一個資料(比如在a表中專門建一行資料,主鍵設定為0,永遠不會對這行資料執行删除操作),這樣就消除了要被删除的資料在ab兩個表中的關系。然後就可以使用删除事務,先删除a表中的資料,再删除b表中的資料,以達到和插入事務表通路一緻,避免死鎖。
3 在外鍵關系中,将“删除規則”設定為“層疊”,這樣删除事務隻需要直接去删除主表a,而不需要對子表b進行操作。因為删除規則設定為層疊以後,删除主表中的資料,子表中所有外鍵關聯的資料也同時删除了。
以上三個解決辦法都是同僚給出的建議,我也不知道到底該使用什麼辦法才好。
不知道對于這種情況要防止死鎖大家還有沒有什麼其他好辦法?