简体   繁体   中英

Transaction scope in HostingEnvironment.QueueBackgroundWorkItem time out

We are using the HostingEnvironment.QueueBackgroundWorkItem to queue long-running background tasks. 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.

Question: Why do we not get a transaction time out an exception when using 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM