事务死锁和 DBContext
本文关键字:DBContext 死锁 事务 | 更新日期: 2023-09-27 18:34:21
嗨,我正在使用实体框架 4.1 代码优先方法。我有继承DBContext
的类MyContainer
。
我有一个过程,每个步骤有 7 个步骤,每个步骤访问许多存储库方法(大约 60 个(。此过程自动执行或每年执行一次,具体取决于业务逻辑和用户要求。现在,从自动过程的性能角度来看,我创建了上下文,即MyContainer
的对象一次,并将其传递给所有方法,并在过程结束时将其处理,并且其工作正常并提高性能。但是,当此过程每年执行一次时,将执行相同的方法,并在方法本身中创建和处置容器。例如下面,但它只是粗略的代码。
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;
}
对于自动处理,事务在流程开始时创建,在流程结束时结束,对于手动事务,在根据用户对 ui 的操作调用的方法中在 bll 创建。现在假设我的自动进程正在运行,同时用户在 ui 上执行了一些操作,我得到异常"Transaction (Process ID 65)
在另一个进程的锁定资源上死锁并已被选中" 当 UpdateProcess(( 方法从 myear 和自动进程一起调用时,我在容器上得到它。保存更改((。
任何帮助将不胜感激。
如果我在这个存储库方法中创建一个事务范围,例如
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;
}
它工作正常。但是我不想在存储库中创建事务,因为事务已经在 blll 中进行。
任何帮助都将得到赞赏。
您遇到的问题(sql 死锁(对于大多数非平凡的客户端 - 数据库系统都很常见,并且可能很难解决。
在设计可能发生死锁的代码时,主要规则是假定它们会并设计应用程序以适当地处理它们。这通常通过重新提交交易来处理。正如微软在这里记录的那样
尽管死锁可以最小化,但无法完全避免。这就是为什么前端应用程序应该设计为处理死锁的原因。
为了尽量减少您看到的任何死锁,我采取的正常方法如下:
- 在启用死锁图的情况下运行探查器以捕获所有死锁
- 将所有死锁导出为文本并调查它们发生的原因 检查是否可以通过使用
- 表提示和/或降低转换隔离级别来最大程度地减少这些情况
- 看看它们是否可以通过其他方式最小化,例如改变操作顺序 最后,在
- 所有这些完成后,请确保在与数据库通信并重新提交事务/查询等时捕获死锁。