Problem with TransactionScope and Asynchronous Calls with EF6

I have the following code designed to break a voluminous EF file into smaller pieces, supposedly to improve performance.

var allTasks = arrayOfConfigLists
        .Select(configList =>
            Task.Run(() => SaveConfigurations(configList))
        .ToArray();

Task.WaitAll(allTasks);

Each call to SaveConfigurations creates a new context that runs until completion.

private static void SaveConfigurations(List<Configuration> configs)
{
    using (var dc = new ConfigContext())
    {
        dc.Configuration.AutoDetectChangesEnabled = false;
        dc.SaveConfigurations(configs);
    }
}

In its current form, the code works relatively efficiently, given that this may not be the best way to do things. However, if one of the SaveConfigurations errors failed, I realized that I would need to roll back any other configurations that were saved in the database.

After some research, I upgraded existing frameworks to 4.5.1 and used the new TransactionScopeAsyncFlowOption.Enabled option to handle asynchronous calls. I made the following change:

using (var scope = 
    new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
    //... allTasks code snippet from above
    scope.Complete();
}

:

.

Open.

(MSDTC) .

/ .

, TransactionScope . , , EF, TransactionScope , . , MSDTC.

, ? ?

Update: , , Database.BeginTransaction() EF. , , . , , .

+4
2

async. , . . .

, -.

, - . , , , DML, EF.

MARS , . , - . ,

+3

i.e attach entities . .

, . ,

, Entity framework .

 public SaveConfigurations(List<Configuration> configs)
    {
        try
        {

            using (var dc = new ConfigContext())
            {
               dc.Configuration.AutoDetectChangesEnabled = false;
               foreach(var singleConfig in configs)
               {
                 //Donot invoke dc.SaveChanges on the loop.
                 //Assuming the SaveConfiguration is your table.
                 //This will add the entity to DbSet<T> , Will not insert to Db until you invoke SaveChanges
                 dc.SaveConfiguration.Add(singleConfig);
               } 
               dc.Configuration.AutoDetectChangesEnabled = true;
               dc.SaveChanges();
            }

        }
        catch (Exception exception)
        {
           throw exception
        }

    }
+1

Source: https://habr.com/ru/post/1615135/


All Articles