Preparing for multiple EF contexts on a unit of work - TransactionScope

Deadly 提交于 2019-12-03 17:06:31

Why do you start TransactionScope in constructor? You need it only for saving changes.

public void SaveChanges()
{
    // SaveChanges also uses transaction which uses by default ReadCommitted isolation
    // level but TransactionScope uses by default more restrictive Serializable isolation
    // level 
    using (var scope = new TransactionScope(TransactionScopeOption.Required,
                                            new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted }))
    {
        _context.SaveChanges();
        scope.Complete();
    }
}

If you want to have unit of work with more contexts you will simply wrap all those context in the same unit of work class. Your SaveChanges will become little bit more complicated:

public void SaveChanges()
{
    using (var scope = new TransactionScope(TransactionScopeOption.Required,
                                            new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted }))
    {
        _contextA.SaveChanges(SaveOptions.DetectChangesBeforeSave);
        _contextB.SaveChanges(SaveOptions.DetectChangesBeforeSave);
        scope.Complete();
        _contextA.AcceptAllChanges();
        _contextB.AcceptAllChanges(); 
    }
}

This version separate saving operation from reseting inner state of the context. The reason is that if the first context successfully saves changes but the second fires exception the transaction will be rolled back. Because of that we don't want the first context to have already cleared all changes as accepted (we would lose information about performed changes and we will not be able to save them again).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!