一些背景信息:
通過刪除舊數據並插入新數據來定期更新數據。 數據被聚集到配置文件中,我將其用作主鍵的一部分,並用於刪除舊數據。
只有一個進程寫入數據,所以不必擔心別人更新衝突。
其他進程只讀取我計劃通過快照隔離解決的數據。
我通過實體框架6訪問數據,代碼優先建模。SQL並行刪除鎖定
問題: 我開始收集幾個並行的配置文件的數據。適用於所有使用簡單外鍵關係但具有自引用關係的表格。
public class Web
{
public Web()
{
CacheDate = DateTime.Now;
}
[Key, Column(Order = 0)]
public Guid ProfileGuid { get; set; }
[Key, Column(Order = 2)]
public Guid WebId { get; set; }
public string Data { get; set; }
public virtual List<List> Lists { get; set; }
public virtual List<Web> SubWebs { get; set; }
public Guid? ParentProfileGuid { get; set; }
public Guid? ParentWebId { get; set; }
public virtual Web ParentWeb { get; set;}
}
modelBuilder.Entity<CacheWeb>()
.HasMany(e => e.SubWebs)
.WithOptional(e => e.ParentWeb)
.HasForeignKey(e => new { e.ParentProfileGuid, e.ParentWebId })
.WillCascadeOnDelete(false);
由於性能問題,我不使用EF刪除數據,但自定義SQL命令:InsertContext.Database.ExecuteSqlCommand(String.Format("DELETE FROM Webs WHERE ProfileGuid = '{0}'", profile.Guid));
如果我叫兩個併發事務這些刪除的,在第一次調用創建一個鎖,阻止第二筆交易繼續。
據我所知,該鎖以某種方式連接到自我引用的索引。
我剛發現另一個奇怪的行爲,它取決於哪個事務先刪除。 我可以找到的數據唯一的區別是父子關係的深度。
如果我先運行事務A(有一個父節點和幾個直接子節點),事後我不能運行事務B(有一些父 - >子 - >子節點關係),但是如果我先運行B,用現有的鎖進入麻煩。
有沒有辦法解決這個問題?或者有什麼想法可能是鎖的問題? 如果您需要更多信息,請評論您的需求,因爲我不確定什麼是重要的。
編輯:澄清
BEGIN Transaction t1
DELETE FROM Webs WHERE ProfileGuid = 'b35dbba4-54fc-4df7-b1c8-e559d81dfee3'
BEGIN Transaction t2
DELETE FROM Webs WHERE ProfileGuid = 'b35dbba4-54fc-4df7-b1c8-e559d81dfee4'
作品。交換訂單,t1必須等待t2完成。
EDIT3:型號和完整查詢 執行計劃是從第三查詢(CacheList的刪除)
BEGIN Transaction t1
DELETE FROM CacheItems WHERE ProfileGuid = 'B35DBBA4-54FC-4DF7-B1C8-E559D81DFEE3'
DELETE FROM CacheFolders WHERE ProfileGuid = 'B35DBBA4-54FC-4DF7-B1C8-E559D81DFEE3'
DELETE FROM CacheLists WHERE ProfileGuid = 'B35DBBA4-54FC-4DF7-B1C8-E559D81DFEE3'
DELETE FROM CacheWebs WHERE ProfileGuid = 'B35DBBA4-54FC-4DF7-B1C8-E559D81DFEE3'
您可以使用TSQL_Locks模板運行SQL Server跟蹤併發布死鎖圖嗎?這將顯示死鎖的確切細節 – Vanlightly
我試過了,它沒有寫入任何事件到死鎖事件文件。可能是因爲沒有死鎖? (之前從未使用該圖)。只要我進行一筆交易,另一筆交易順利進行。但是由於一項交易可能需要長達一個小時的時間,因此等待不是一種選擇。 – lolsharp
您會看到一系列事件,如鎖定:死鎖鏈,死鎖圖。 – Vanlightly