【发布时间】:2015-11-30 14:31:23
【问题描述】:
一些背景信息:
通过删除旧数据并插入新数据来定期更新数据。
数据聚集到配置文件中,我将其用作主键的一部分并用于删除旧数据。
只有一个进程写入数据,因此不必担心其他人的更新冲突。
其他进程仅读取我计划通过快照隔离解决的数据。
我通过实体框架 6 访问数据,代码优先建模。
问题: 我开始并行收集多个配置文件的数据。适用于所有具有简单外键关系的表,但适用于具有自引用的表。
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,我可以在之后运行 A 而无需进入现有锁有问题。
有没有办法解决这个问题?或者知道锁可能有什么问题吗? 如果您需要更多信息,请评论您究竟需要什么,因为我不确定什么是重要的。
编辑:澄清
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:模型和完整查询 执行计划来自第 3 次查询(删除 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 跟踪并发布死锁图?这将显示死锁的确切细节
-
我试过了,它没有向死锁事件文件写入任何内容。大概是因为没有死锁吧? (以前从未使用过该图)。一旦我提交一项事务,另一项事务就会顺利运行。但由于一项交易可能需要长达一个小时的等待时间,因此无法选择。
-
您会看到一系列事件,例如 Lock:Deadlock Chain, Deadlock Graph。
-
删除查询似乎与计划无关。您可以添加表结构以及非聚集索引吗?然后我可以重新创建场景。
-
我的错,错误现在出现在另一个查询中,我将添加完整的表结构和新查询
标签: sql-server entity-framework concurrency transactions