試在sqlserver2000上進行,對工作流操作的相關方法在單元測試里進行多線程并發。測試發現sqlserver出現死鎖的情況相當多,一些典型的情況:
1、對同一張表先insert再update是很快會引起死鎖的,不管操作的是否是同一記錄
解決方法:對于同一記錄,需要調整hibernate的映射策略,使得一次insert完成操作。對于不同的記錄需要在代碼中手動flush,使得update先于insert。
2、對兩張表進行多次update操作時,兩張表交替update也會很快引起死鎖
解決方法:在代碼中手動flush,保證對兩張表的update不會出現交替的情況。
3、部分大范圍掃描的select和update混合也會導致死鎖
解決方法:優化sql,盡量減少sql語句,通過給po增加持久化字段的方式減少關聯查詢
經過優化,大部分情況下數據庫死鎖的情況得以避免,另外奇怪的是通過事件探查器在死鎖時并未發現鎖升級的事件。但是在一些特殊情況下(例如多個并發匯聚的直接聯合),死鎖依舊發生。最后不得不對方法進行synchronized關鍵字同步,這個通過synchronized flush完成。業務方法不必同步,最后批量操作數據庫時進行同步。
換oracle進行測試,在未synchronized的情況下,未發生死鎖情況。由此可見sqlserver與oracle鎖實現機制存在很大的差別。對sqlserver鄙視之。另,同事說,sqlserver2012后性能和機制發生了很大的變化,未測試。