Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EntityFramework SaveChanges intermittent exception due to "pending requests working on this transaction"

I have written a service which runs a SchedulerCallback once a day and does various work and updates a MS SQL database using EntityFramework 6.1.3, ApplicationUserManager and LINQ

After each task it saves the changes using SaveChanges on a global context that lives within the class, but every few weeks one or more of the SaveChanges fail with: "The transaction operation cannot be performed because there are pending requests working on this transaction".

The scheduler looks like this:

Timer Scheduler = new Timer(new TimerCallback(SchedulerCallback))

All the SaveChanges are done after any loops and I have been unable to discover what I am doing wrong in the Entity Framework documentation or on Stack Overflow.

A much simplified example of my service class ignoring the scheduling and performing only one task and SaveChanges:

public partial class MyService : ServiceBase
{
    private MyContext myContext { get; set; }
    private ApplicationUserManager UserManager { get; set; }

    public MyService()
    {
        MyContext = new MyContext();
        UserManager = new ApplicationUserManager(new UserStore<ApplicationUser>(MyContext));
    }

    private void SchedulerCallback()
    {
        var users = (from u in MyContext.Users where u.Status = StatusFlag.PlaceOrder select u.User).ToList();

        foreach (var user in users)
        {
            myContext.Order.Add(new MyOrder());
            myContext.Order.User = user;

            OrderTransaction transaction new OrderTransaction();
            order.Transactions = new List<OrderTransaction>();
            order.Transactions.Add(transaction);

            user.Status = StatusFlag.OrderPlaced;
        }

        try
        {
            myContext.SaveChanges();
        }
        catch (Exception e)
        {
            Logger.LogError("Exception", e);
        }
    }   
}

In my service SchedulerCallback does a lot more and calls SaveChanges() on the context multiple times, but not in a loop but rather for various tasks. It is not the first time I call SaveChanges that the error occurs, at least not so far, but then again it doesn't happen very often so it is hard to establish any pattern.

What am I doing wrong?

like image 856
Tarostar Avatar asked Sep 03 '25 17:09

Tarostar


1 Answers

Timer's callback is executed in different threads (similar problem), but DbContext is not thread safe, so create context just before doing any work:

public partial class MyService : ServiceBase
{
    private void SchedulerCallback()
    {
        using (var myContext = new MyContext())
        {
            var UserManager = new ApplicationUserManager(new UserStore<ApplicationUser>(MyContext));

            var users = (from u in myContext.Users where u.Status = StatusFlag.PlaceOrder select u.User).ToList();

            foreach (var user in users)
            {
                myContext.Order.Add(new MyOrder());
                myContext.Order.User = user;

                OrderTransaction transaction = new OrderTransaction();
                order.Transactions = new List<OrderTransaction>();
                order.Transactions.Add(transaction);

                user.Status = StatusFlag.OrderPlaced;
            }

            try
            {
                myContext.SaveChanges();
            }
            catch (Exception e)
            {
                Logger.LogError("Exception", e);
            }
        }
    }   
} 
like image 108
Ivan R. Avatar answered Sep 06 '25 10:09

Ivan R.