简体   繁体   English

事务死锁和DBContext

[英]Transaction Deadlock and DBContext

Hi i am using Entity Framework 4.1 code first approach . 您好我正在使用Entity Framework 4.1代码的第一种方法。 I have class MyContainer that inherits DBContext . 我有继承DBContextMyContainer

I have a process that has 7 steps each step accesses many repository methods (about 60) .This process executes automatically or mannually depends upon business logic and user requirement . 我有一个流程,每个步骤有7个步骤访问许多存储库方法(大约60个)。此流程自动执行或手动执行取决于业务逻辑和用户需求。 Now for performance point of view for automatic process i created context ie object of MyContainer once and pass it to all methods and dispose it at the end of process and its working fine and improved the performance.But when this process is executed mannually same methods are executed and container is created and disposed in the method itself. 现在为自动过程的性能观点我创建上下文即MyContainer对象一次并将其传递给所有方法并在流程结束时将其处理并且其工作正常并提高了性能。但是当此过程执行时,同样的方法是执行和容器在方法本身中创建和处理。 eg below but it is just rough code. 例如下面但它只是粗略的代码。

public bool UpdateProcess(Process process, MyContainer container = null)
    {
        bool disposeContainer = false;
        if (container == null)
        {
            container = new MyContainer();
            disposeContainer = true;
        }
        var result = SaveProcess(container, process);
        container.SaveChanges();
        if (disposeContainer)
            container.Dispose();
        return result;
    }

For Automatic Process transaction is created at the beginning of the process and ended at the end of the process and for manual transaction is created at the bll in the method which is called according to the user action on ui.Now suppose my automatic process is running and simultaneously user did some action on ui I gets the Exception "Transaction (Process ID 65) Was Deadlocked On Lock Resources With Another Process And Has Been Chosen" When the UpdateProcess() method is called together from both mannual and automatic process, I get it on container.SaveChanges(). 对于自动流程事务,在流程开始时创建并在流程结束时结束,并且在方法中的bll中创建手动事务,该方法根据ui上的用户操作调用。现在假设我的自动流程正在运行同时用户对ui做了一些操作我得到了异常"Transaction (Process ID 65)已经被锁定资源与另一个进程被锁定并被选中”当UpdateProcess()方法从mannual和自动进程一起被调用时,我得到了它在container.SaveChanges()上。

Any help will be highly appreciated. 任何帮助将受到高度赞赏。

If i create a transaction scope in this repository method like 如果我在这个存储库方法中创建一个事务范围,如

public bool UpdateProcess(Process process, MyContainer container = null)
 {         bool disposeContainer = false;        
           if (container == null)  
           {             
                  container = new MyContainer();         
                  disposeContainer = true;         
            }
       using(var trans=new TransactionScop(TransactionScopeOption.RequiresNew))        
       { 
          var result = SaveProcess(container, process);
          container.SaveChanges();
          trans.Complete();
       }        
          if (disposeContainer)           
          container.Dispose();        
          return result;   
 } 

It works fine. 它工作正常。 However I dont want to create the transaction in repository as the transactions been already made in bll. 但是我不想在存储库中创建事务,因为事务已在bll中进行。

Any help will be appericiated. 任何帮助都将得到帮助。

The issue (sql deadlocking) you are having is common to most non-trivial client - database systems and can be very difficult to resolve. 您遇到的问题(sql死锁)对于大多数非平凡的客户端 - 数据库系统来说都很常见,而且很难解决。

The primary rule in designing code where deadlocks may occur is to assume that they will and design the application to handle them appropriately. 设计可能发生死锁的代码的主要规则是假设它们将设计应用程序以适当地处理它们。 This is normally handled via resubmitting the transaction. 这通常通过重新提交事务来处理。 As documented by microsoft here 正如微软在这里所记录的那样

Although deadlocks can be minimized, they cannot be completely avoided. 尽管可以最小化死锁,但不能完全避免死锁。 That is why the front-end application should be designed to handle deadlocks. 这就是为什么前端应用程序应该设计为处理死锁的原因。

In order to minimise any deadlocks you are seeing the normal approach I take is as follows: 为了最大限度地减少任何死锁,您会看到我采取的正常方法如下:

  1. Run profiler with a deadlock graph enabled to capture all deadlocks 运行探查器并启用死锁图以捕获所有死锁
  2. Export all deadlocks to text and investigate why they are occurring 将所有死锁导出到文本并调查它们发生的原因
  3. Check to see these can be minimised by using table hints and/or reducing the transation isolation level 通过使用表提示和/或降低转换隔离级别来检查这些是否可以最小化
  4. See if they can be minimised by other means, eg changing the order of operation 看看是否可以通过其他方式最小化它们,例如改变操作顺序
  5. Finally after all this has been completed ensure that you are trapping for deadlocks anytime you communicate with the database & resubmit the transaction / query etc. 最后,在完成所有这些操作后,确保在与数据库通信时随时捕获死锁并重新提交事务/查询等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM