EF6:同时进行多笔交易

时间:2015-12-23 10:34:12

标签: c# asp.net asp.net-mvc entity-framework transactions

我的项目有两个部分:一个收集一些数据的Powershell脚本和一个接收数据(作为文件)并将它们集成到数据库中的ASP.NET 4.5 MVC应用程序(带有Entity Framework 6.1.3)。将有大约1500个文件发送到ASP.NET应用程序。

我需要使用事务:如果在向数据库添加数据时发生错误,则不必添加任何内容(回滚)。添加此功能不是问题。但似乎在事务开始时,另一个事务在第一个提交或回滚之前无法开始。这很糟糕,因为我的1500个文件必须逐个添加,并且由于积分时间为+/- 5分钟,所以需要花费很多时间。

我不知道我犯了什么错误。这是我的代码:

public bool JsonToDB(dynamic data)
{
    using (MyEntities context = new MyEntities())
    {                
        context.Database.CommandTimeout = 300;
        context.Configuration.AutoDetectChangesEnabled = false;
        context.Configuration.ValidateOnSaveEnabled = false;

        using (var transaction = context.Database.BeginTransaction(IsolationLevel.ReadUncommitted))
        {
            try
            {           
                // DB integration from the file provided by the Powershell script.

                context.SaveChanges();

                transaction.Commit();
                transaction.Dispose();              

                return true;
            }
            catch (Exception e)
            {
                // Error management.

                transaction.Rollback();                        
                transaction.Dispose();

                return false;
            }
        }
    }
}

public Task FileIntegration(string fileDirectory, string fileName)
{
    return Task.Factory.StartNew(() =>
    {
        try
        {
            string fileContent = System.IO.File.ReadAllText(fileDirectory + "JSON/" + fileName, Encoding.ASCII);

            var serializer = new JavaScriptSerializer();
            serializer.RegisterConverters(new[] { new DynamicJsonConverter() });

            dynamic data = serializer.Deserialize(fileContent, typeof(object));

            if (JsonToDB(data))
            {                    
                System.IO.Directory.Move(fileDirectory + "JSON/" + fileName, fileDirectory + "JSON/Success/" + fileName);               
            }
            else
            {
                System.IO.Directory.Move(fileDirectory + "JSON/" + fileName, fileDirectory + "JSON/Error/" + fileName);
            }
        }
        catch(Exception e)
        {
            System.IO.Directory.Move(fileDirectory + "JSON/" + fileName, fileDirectory + "JSON/Error/" + fileName);
        }
});
}

[HttpPost]
[AllowAnonymous]
public ActionResult Receive(HttpPostedFileWrapper file)
{
    try
    {
        file.SaveAs(Server.MapPath("~") + "/Files/JSON/" + file.FileName);

        HostingEnvironment.QueueBackgroundWorkItem(ct => {
            return FileIntegration(Server.MapPath("~") + "/Files/", file.FileName);
        });
    }
    catch (Exception e)
    {
        return new HttpStatusCodeResult(400, "Unable to save the JSON file. Detailed error: " + e.Message);
    }

    return new HttpStatusCodeResult(200, "OK");
}

我还尝试使用SaveChangesAsync方法保存更改(https://stackoverflow.com/a/28133913),但发生错误:

  

提交数据库事务时报告了错误,但无法确定数据库服务器上的事务是成功还是失败。

你有什么想法可以帮助我解决这个问题吗?

提前致谢。

编辑:更清楚:指令context.SaveChanges();无法同时为多个交易执行。要应用其更改,事务必须等待其他更改应用程序的结束。我想要的是能够有多个方法实例保存他们的更改而无需等待。数据库集成仅包含DB中的插入和删除(无更新)。

1 个答案:

答案 0 :(得分:0)

您需要使用TransactionScope课程。这是一个例子

using (TransactionScope scope = new TransactionScope())
{
    //Do something with context1
    //Do something with context2

    //Save and discard changes
    context1.SaveChanges();

    //Save and discard changes
    context2.SaveChanges();

    //if we get here things are looking good.
    scope.Complete();
}