【发布时间】:2018-02-01 19:48:58
【问题描述】:
我有以下异步方法,可以删除记录并将记录插入 MySQL 数据库
public async Task<Res> myNewFunc(int id, IEnumerable<Sample> obs)
{
using (var t = DbConnection.GetTransaction())
{
await DbConnection.DeleteMany<M1>().Where(x.Id == id).ExecuteAsync();
foreach (var ob in obs)
{
await DbConnection.InsertAsync(ob);
}
t.Complete();
}
}
调用 myNewFunc() 的方法:
public async Task<T> method()
{
//...
//...
var response = await DAL.myNewFunc(id, obs);
}
使用 foreach 循环访问异步方法。
foreach(var num in nums)
{
method();
}
我在使用上面的代码时遇到了 MySQL 的死锁问题。
【问题讨论】:
-
foreach看起来很奇怪;您正在迭代nums但不使用该值。您正在调用method()而不等待它或存储任务以供稍后等待。 -
只有锁的范围在中途扩展时才会出现死锁。积极锁定您可能需要的任何资源很重要,而不仅仅是您确定会需要的资源。如果没有看到 SQL,真的很难判断 DB 端会发生什么。
-
同意@Christopher,您应该查看数据库并找到导致死锁的实际原因。我不熟悉解决 MySql 中的死锁问题,但快速搜索表明您可以找到导致问题的实际语句。
-
由于 foreach 没有等待,它将在不停止/暂停/等待的情况下运行所有迭代。这将导致 X 个“方法”调用被连续触发。每个人都会立即调用 myNewFunc 并等待。然后这会调用您的 DeleteMany 并等待。但是对 myNewFunc 和 DeleteMany 的调用并不知道对方,如果他们试图删除同一张表中的东西,你会遇到死锁,正如你所看到的。这将与该删除中调用的触发器和其他表一起传播。
-
t.commit()而不是完整的呢?
标签: c# mysql multithreading entity-framework async-await