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