2012-03-02 30 views
0

我有一個分佈式客戶端服務器系統,它有多個'工作'引擎和一個WCF服務,我們可以稱之爲FileManagerService,它將'作業'添加到數據庫'工人'發動機來接受和處理。如何在LINQ中實現數據庫記錄互斥sql

數據庫由兩個表組成:JobsFile。每項工作都以File(多對一關係)運作。可以一次將多個作業添加到Jobs表中,它們按照隊列的方式進行處理。

Job

的是操作,例如:MoveFile或的DeleteFile等

我試圖通過使用來實現對File記錄互斥‘在File表本身鎖定’(布爾)列。

我認爲需要的互斥區域在WCF服務FileManagerService的方法:addJob()以及'工作'引擎'TakeAndProcessAJob()內。

目前我遇到了linq-to-sql延遲執行以及linq-to-sql事務系統如何工作的問題。

目前,我有以下方法,應該從Jobs表採取Job,檢查其相關File被鎖定,如果被鎖定,我們將返回任何結果,如果它沒有被鎖定,我們將鎖定File和返回Job,並從Jobs隊列中刪除Job

public static Job GetAnAvailableJob() 
{ 
    using (DBDataContext db = new DBDataContext()) 
    { 
     DataLoadOptions loadOptions = new DataLoadOptions(); 
     loadOptions.LoadWith<Job>(f => f.File); 
     db.LoadOptions = loadOptions; 
     var jobAvailable = from ja in db.Jobs 
            where ja.File.locked == false 
            select ja; 
     var jobToTake = jobAvailable.FirstOrDefault(); 
     // This file temp is here so that we can return 
     // an associated File with the Job. 
     // We delete 
     File fileTemp = null; 
     if (jobToTake != null) 
     { 
      fileTemp = jobToTake.File; 
      jobAvailable.File.locked = true; 
      Console.WriteLine("Locked file:" + fileTemp.FileID); 
      db.Jobs.DeleteOnSubmit(jobToTake); 
      db.SubmitChanges(); 
      jobToTake.Asset = fileTemp; 
     } 
     return jobToTake; 
    } 
} 

的「工人」引擎TakeAndProcessAJob()基本上具有下列功能:呼叫GetAnAvailableJob(),如果返回的對象不爲空 - > proccess的工作,如果是空 - >睡覺。

WCF服務FileManagerService使用此鎖定方法:

public static bool LockAsset(long FileID) 
{ 
    using (DBDataContext db = new DBDataContext()) 
    { 
     var fileToLock = db.Files.Where(f => f.FileID == FileID && f.locked == false).Single(); 
     if (fileToLock == null) 
     { 
      return false; 
     } 
     else 
     { 
      Console.WriteLine("Locked File:" + fileToLock.AssetID); 
      fileToLock.locked = true; 
      db.SubmitChanges(); 
      return true; 
     } 
    } 
} 

什麼我需要在這兩種方法來改變,使隨後的行爲在一個事務的方式和對File記錄互斥。目前,我在TakeAndProcessAJob()方法中的SubmitChanges()上收到更改衝突異常 - 行未更改或找到。

感謝

回答

0

我找不出我的問題的答案,所以我做了一些邏輯重組,並設計了一個使用普通舊SQL的解決方法。要鎖定我現在記錄使用單個線(原子)命令的記錄:

UPDATE dataTable SET locked = 'True' WHERE (locked = 'False') AND (recordID= 15)

我然後使用SqlDataReader並檢查RecordsAffected字段。如果記錄已更改,則表示我已成功鎖定記錄。如果記錄沒有改變,這意味着記錄已經被鎖定,所以我在我的鎖定方法上返回false

嘗試鎖定記錄的進程然後位於while循環中,調用lockRecord並等待成功回調。

我不確定是否完全有必要從LINQ切換到SQL。我在我的應用程序中進行了邏輯更改,並且開關同時計劃了SQL,因此很難確定使用LINQ是否是問題。

0

那「行沒有改變或者找到」錯誤可以爲你的數據庫模型文件不符合實際的物理數據庫架構簡單的東西。

另一個原因可能是,LINQ沒有檢測到任何更改提交。說出你選擇的記錄是否爲真,並將其標記爲真。你可以通過不更新,如果它已經是真實的,或者可能的原因是在模式文件下的表格上的該字段的屬性下有一個設置,你實際上可以關閉UpdateCheck,但它聽起來並不像這樣想。

在一個不相關的故事: 沒有「.Single()」拋出一個錯誤,當沒有什麼被發現作爲firstOrDefault(),只是返回null?