[英]Transaction scope in HostingEnvironment.QueueBackgroundWorkItem time out
We are using the HostingEnvironment.QueueBackgroundWorkItem to queue long-running background tasks. 我们使用HostingEnvironment.QueueBackgroundWorkItem对长时间运行的后台任务进行排队。 This works great, however, when the transaction times out, we don't get any exceptions and the thread seems to be killed or hanging.
这很好用,但是,当事务超时时,我们不会得到任何异常,并且线程似乎被杀死或挂起。
Does anyone know what is happening here? 有谁知道这里发生了什么? I was expecting a Transaction time out exception or something related... We noticed that the thread hangs after the time out when using a DbContext, without DbContext we are getting a transaction time out.
我期待一个事务超时异常或相关的东西...我们注意到线程在使用DbContext超时后挂起,没有DbContext我们得到一个事务超时。
Question: Why do we not get a transaction time out an exception when using EF DbContext? 问题:为什么在使用EF DbContext时我们没有获得超时的事务处理时间?
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Hosting;
using System.Web.Mvc;
using Timer = System.Timers.Timer;
namespace WebApplication5.Controllers
{
public class HomeController: Controller
{
public ActionResult Index()
{
ViewBag.Title = "Home Page";
HostingEnvironment.QueueBackgroundWorkItem(cancellationToken =>
{
try
{
try
{
var dbContext = new TestDbContext();
using (var backgroundTimer = CreateTimerWhichExtendsLocks((10)))
{
using (var Tran =
TransactionScopeBuilder.CreateWithDefaultIsolationLevel(timeout: new TimeSpan(0, 0, 30)))
{
try
{
int i = 0;
do
{
var d = dbContext.MyTestEntities.SingleOrDefault(x => x.Id == 1);
Thread.Sleep(500);
i++;
Debug.WriteLine(i);
} while (i < 100);
}
catch (Exception e)
{
Debug.WriteLine(e);
throw;
}
tran.Complete();
}
}
}
catch (Exception e)
{
Debug.WriteLine(e);
throw;
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
throw;
}
});
return View();
}
private static Timer CreateTimerWhichExtendsLocks(int lockDurationInMs)
{
var backgroundTimer = new Timer(300);
backgroundTimer.Elapsed += (sender, e) =>
{
Debug.WriteLine(DateTime.Now);
};
backgroundTimer.Start();
return backgroundTimer;
}
}
} }
This seems to be a known issue in efcore 2.x, which is fixed in the 3.x release. 这似乎是efcore 2.x中的已知问题,已在3.x版本中修复。
https://github.com/aspnet/EntityFrameworkCore/issues/14218 https://github.com/aspnet/EntityFrameworkCore/issues/14218
When the operation in the transaction takes longer than the timeout on the ambient transaction, the connection gets closed by the ambient transaction but the inner method is not aware of this and tries to reopen the connection which makes the the program get stuck in a deadlock situation. 当事务中的操作花费的时间超过环境事务的超时时,环境事务会关闭连接,但内部方法不知道这一点并尝试重新打开连接,这会使程序陷入死锁状态。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.