SQL的实体框架操作 - 防止死锁

时间:2010-12-11 00:11:29

标签: sql-server entity-framework deadlock

我在SQL Server中有一个类似于:

的表
Col1  Id  -Int and Key    
Col2  ProductId  int    
Col3  ProductDesc   Varchar

在我的Silverlight应用程序中,我有两个网格显示此表中的数据 - 由ProductId分隔 - 换句话说,我将所有产品A放在一个网格中,所有产品B放在另一个网格中。

当我选择任何一个项目中的任何项目时,我会把它写到表格中。如果我从网格中取消选择一个项目,我会从该网格中删除该行。由于Silverlight使用异步调用,当一个网格繁忙时,用户仍然可以使用其他网格(这就是我想要的)。但是,如果用户在从另一个项目插入项目时取消选择一个网格中的项目,则会出现死锁错误。

我的所有插入都是在每个实体更新后完成的,我调用了SubmitChanges()。删除操作以不同的方式处理。由于EF中没有DeleteAll,我使用对象上下文的ExecuteStoreCommand()并提交DELETE查询 - 这可能是我的问题所在。

如何在不出现死锁错误的情况下使用同一个表来完成此操作?我真的试图避免为每个网格创建一个单独的表。

如果我使用EF从我的实体中删除而不是ExecuteStoreCommand(),EF会更好地处理死锁吗?将表加载到内存中似乎是一个资源腰,每次删除一行。

编辑:我想补充一点,我确认在我插入EF时同时从talbe中删除我的死锁。

谢谢,

-Scott

3 个答案:

答案 0 :(得分:1)

尝试为您的交易使用隔离级别:

using (TransactionScope scope = 
          new TransactionScope(TransactionScopeOption.RequiresNew, 
             new TransactionOptions() 
             {
                IsolationLevel = IsolationLevel.ReadUncommitted 
             }))
{
   // read only work - no locks on records. effectively SELECT xx from xxx WITH (NOLOCK)
}

但是,AFAIK这是用于确定EF上下文查询的范围。如果您使用ExecuteStoreCommand,那么您可能必须手动将NOLOCK提示放在查询本身上。

答案 1 :(得分:0)

你的删除语句是否与其他操作触及相同的行?

如果没有,请尝试添加一个rowlock提示:从xyz删除(rowlock)where ...

答案 2 :(得分:0)

以下适用于我。

using (var context = new XXX())   // Replace XXX with your specifics
{
  context.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;"); 
  // your LINQ code here
}