小記:事務(進程 ID 56)與另外一個進程被死鎖在 鎖 | 通訊緩衝區 資源上,而且已被選做死鎖犧牲品。

今天在作SQL併發UPDATE時遇到一個異常:(代碼以下)數據庫

//Parallel 類可產生併發操做(即多線程)
Parallel.ForEach(topics, topic =>
{
    //DBHelper是一個封裝的數據庫操做類,下面這行代碼將執行UPDATE語句
    DBHelper.Update(topic, "TopicID=" + topic.TopicID);
});

出現此問題的緣由是,在SQLServer默認狀況下,一條SQL語句就是一個事務。而在多線程同時UPDATE時,會同時產生多個事務,A事務等待B事務結束,B事務等待A事務結束,則形成了死鎖。多線程

解決方法:lock 加鎖 (即:在多個線程同時訪問 lock 代碼區時,只容許一個線程進入,其餘線程處於等待狀態)併發

//聲明靜態只讀鎖對象
private static readonly object o = new object();

Parallel.ForEach(topics, topic =>
{
    //加鎖
    lock (o)
    {
        //同一時刻僅能有一個線程進入
        DBHelper.Update(topic, "TopicID=" + topic.TopicID);
    }
});
相關文章
相關標籤/搜索