【发布时间】:2021-11-11 00:21:45
【问题描述】:
我正在使用 .Net Framework 4.5,但出现以下错误:
“多个同时连接或具有不同连接的连接〜”当前不支持同一事务内的多个同时连接或具有不同连接字符串的连接。 "
我很好奇的是,这个错误并不总是发生,大约 50 次?这意味着每天大约会发生一次错误。 我不知道该怎么办,因为它只发生在生产环境中,而在本地测试中从未发生过。 如果您知道确切原因,请告诉我。
最好的尊重。
简化的来源如下。
public PartialViewResult update(string id)
{
List<Item> list;
try
{
var business = new Business();
using (var ts = new TransactionScope(TransactionScopeOption.Required))
{
business.Update(id);
ts.Complete();
}
if (result)
{
list = business.GetList();
}
else
{
Response.StatusCode = 500;
return PartialView("Error");
}
return PartialView("PartialContent", list);
}
catch (Exception ex)
{
Response.StatusCode = 500;
return PartialView("Error");
}
}
public class Business
{
public List<Item> GetList()
{
var dao = new Repository();
var list = dao.GetList().ToList();
return list;
}
public void Update()
{
try
{
var dao = new Repository();
var item = dao.Get(id);
item.UpdateDate = DateTime.Now;
dao.Update(item);
}
catch (Exception ex)
{
throw ex;
}
}
}
public class Repository
{
private SampleContext context;
private Repository()
{
if (context == null)
{
context = new SampleContext();
}
}
public IQueryable<Item> GetList()
{
// SQL
}
public IQueryable<Item> Get(string id)
{
// SQL
}
public void Update(Item item)
{
context.Entry(item).State = EntityState.Modified;
context.SaveChanges();
}
}
添加。
我试图通过 Le Vu 的评论来修改存储库。
public class Repository : IDisposable
{
private SampleContext context;
private Repository()
{
if (context == null)
{
context = new SampleContext();
}
}
public IQueryable<Item> GetList()
{
// SQL
}
public IQueryable<Item> Get(string id)
{
// SQL
}
public void Update(Item item)
{
context.Entry(item).State = EntityState.Modified;
context.SaveChanges();
}
public void Dispose()
{
context.Dispose();
}
}
中途commit的原因是即使更新后重新获取数据出现错误,我们也希望按原样继续更新过程。
【问题讨论】:
-
您是否尝试在 Repository 中调用 Dispose DbContext。我认为 DbContext 持有与数据库连接相关的非托管资源。
-
应该在什么阶段处理 DbContext?如果在每个进程中都这样做,会是“操作无法完成。DbContext已被销毁”。 * 因为是翻译成英文的,所以可能与实际的英文信息不同。
-
你的
Repository类应该实现IDisposable接口。该接口有Dispose()方法。当 GC 收集未使用的对象时,将调用此方法。您应该在 Repository 的Dispose()中调用 DbContext 配置。另外,请注意您的Business实例生命周期 -
感谢您的评论。您需要使存储库成为一次性的。我将修改后的来源放在正文中。是这样的吗?没有这个,它可能会一直保留而不会被丢弃,是不是意味着在销毁恰好延迟的时候发生了错误?
-
是的,你知道,垃圾收集器是 CLR 的一个特性。这意味着它只关心来自 CLR 环境的资源。这些资源称为托管资源。否则,对于这种情况下的数据库连接等非托管资源,GC 不知道它的存在。无论如何,你错过了在
context上检查null。
标签: c# mysql asp.net-mvc entity-framework