我有以下异步方法删除并将记录插入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的死锁问题。
答案 0 :(得分:-1)
因为您没有在最后一个for循环中等待,所以它将为所有这些循环启动线程并同时并行运行所有这些线程。如果你在这里有很多数据,那么他们都将争夺相同的资源。您最终会在每种情况下创建事务,然后从表中删除多个记录。但是,这可能不是真正的潜在问题。在所有ExecuteAsync调用中,您不执行.ConfigureAwait(false)。这意味着在运行每个语句之后,它会一直等到它可以在原始线程(在本例中为UI线程)上恢复其工作。我不知道你在for循环之后做了什么,但是这个线程可能永远不会放弃,所以这些db调用都不会再回来,你会遇到死锁。
您可以尝试解决此问题的两种方法:
每个Async()调用都需要是Async()。ConfigureAwait(false)。如果真的是UI线程被锁定,这可能会解决它。
在最后一个for循环中,您需要等待每个循环,因为可能数据库资源全部被绑定了。请改用此代码:
SparkConf conf = new SparkConf()
.setAppName("appName")
.setMaster("local");
SparkSession sparkSession = SparkSession
.builder()
.config(conf)
.getOrCreate();
return sparkSession;
这将一次只处理一个。对于#2,你可能也需要做#1。