2011-12-26 66 views
2

我遇到問題。我試圖用並行來更新數據庫庫。下面是代碼:LinqToSql。更新一行時死鎖。 Parallel.For

Parallel.For(rCnt, range.Rows.Count + 1, (jrCnt, loopState) => 
{ 
    var prcI = new Price(); // new 

    /*bla bla bla bla - bla bla - bla bla - bla */ 

    if ((!string.IsNullOrEmpty(prcI.name)) && (prcI.prc != 0)) // process add or update 
    { 
     prcI.company = nameprice; 
     prcI.date = datatimeselect.Text; 

     Accessor.AddProductUpdateProduct(prcI); // main func 

      /*bla bla bla bla - bla bla - bla bla - bla bla - bla */ 
    } 

這裏的功能代碼字段更新:

public static bool AddProductUpdateProduct(Price price) 
    { 
     bool add = false; 
     var db = new PriceDataContext(); 

     var matchedprod = 
      db.Price.Single(x => x.name == price.name && x.date != price.date && x.company == price.company); // find match 

     if (matchedprod != null) // match FOUnDE 
     { 
      if (matchedprod.prc != price.prc) 
      { 
       matchedprod.date = price.date; 
       matchedprod.prc = price.prc; 
      } 
      else 
      { 
       matchedprod.date = price.date; 
      } 
      db.SubmitChanges(); // DEADLOCK is her!!! 
     } 
     /*bla - bla bla - bla bla - bla bla - bla bla - bla */ 
    } 

當我創造了紀錄,一切都很好!

謝謝!

+0

您在這裏更新/插入了多少條記錄? –

+0

與3,000至10,000不同。 – JinDeveloper

回答

2

記錄數在3000到10000之間(註釋)我會在這裏查看一個解決方案,它使用SqlBulkCopy將數據推送到臨時表(即與您正在操作的數據看起來類似的表你的核心模型的一部分)。這是將大量數據傳送到服務器的最有效方式(儘管您也可以查看錶值參數)。然後,我將在服務器上執行一個更新(內部連接)和一個插入(不存在)或單個「upsert」(可在SQL Server 2008及更高版本中使用)。

這會在應用程序服務器使用更少的CPU,減少網絡和數據庫資源。另外,由於插入/更新中只涉及一個SPID,所以不存在死鎖的風險。

+0

現在嘗試使用SqlBulkCopy。數據最好保存在數據表中然後上傳? – JinDeveloper

+0

@Jin你能改說嗎?我不太瞭解你的評論。但是:是的:DataTable是在SqlBulkCopy實例上拋出數據的一種方法。但在此之前它不需要在DataTable中。 –

+0

我讀了關於SqlBulkCopy。它只會增加基地?關於更新沒有找到信息。 – JinDeveloper

0

我想這可能是我在這個問題中描述的同樣的問題Deadlock on SELECT/UPDATE。這不是linq to sql的問題。 linq to sql的問題是你不能用updlock輕鬆執行select。

+0

是的,但沒有隔離級別,應該隔離第一個選擇並在選擇之後釋放任何讀取鎖定;另外,沒有「可序列化」它不應該是一個鍵範圍鎖。不完全相同的情況下,IMO –

+0

我不明白如何實施。我在這個問題上已經有一個星期在掙扎。請告訴我。 – JinDeveloper

+0

你是否需要並行執行?您的問題發生是因爲多個線程正在處理同一個表中的數據。在單線程上執行操作是最簡單的解決方法。否則,我會編寫存儲過程,將使用select with updlock,然後添加或更新。 – empi