Linq to SQL TransactionScope

Old*_*Boy 4 transactionscope linq-to-sql

我有以下场景:

 using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted },EnterpriseServicesInteropOption.Automatic))
 {
  using (DataContext db = new DataContext())
  {
    db.Connection.Open();
    db.Transaction = db.Connection.BeginTransaction();
    try
    {
      bool outcome = InvokeInTransaction<string, object>(inputDict, out outputDict);
      db.Transaction.Commit();
    }
    catch (Exception ex)
    {
      response.Outcome = BusinessEntityResponse.SystemError;
      db.Transaction.Rollback();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

InvokeInTransaction调用内部是对LTS存储库进行的一些调用,以执行各种数据更改.问题是在存储库中还有另一个

using (var db = new DataContext())
Run Code Online (Sandbox Code Playgroud)

里面是持久性代码.检查存储库中的上下文显示Transaction = null,我怀疑"内部"上下文不知道Ambient事务.可以这样做吗?我知道EF管理这个,并且约束是无法更改存储库代码.有帮助吗?

Amy*_*y B 5

我们使用LinqToSql和TransactionScope进行多个数据库事务.如果您要尝试它,您应该真正控制您的连接/上下文/事务生命周期.

  • 我们通过规则控制DataContext实例:如果您新建一个,则使用using语句执行此操作.
  • 我们按规则控制连接生命周期:如果打开它,则必须关闭它(但通常让DataContext实例管理它).
  • 我们通过规则控制事务生命周期:让DataContext管理SubmitChanges中发生的事情,让TransactionScope管理其using块中发生的事情.

这是一个代码示例:

using (OuterDataContext outerDataContext = GetOuterDataContext())
{
  using (InnerDataContext innerDataContext = GetInnerDataContext())
  {
    try
    {
      OuterRepository outerRepository = new OuterRepository();
        // may read records into memory for updating/deleting.
      outerRepository.WorkWithOuterRecords(outerRecords, outerDataContext);

      InnerRepository innerRepository = new InnerRepository();
        // may read records into memory for updating/deleting.
      innerRepository.WorkWithInnerRecords(innerRecords, innerDataContext);

      using (TransactionScope scope = new TransactionScope())
      {
          //starts a local tranaction in outerDB, held open by scope
        outerDataContext.SubmitChanges();  
          //promotes the transaction to distributed, still held open by scope
        innerDataContext.SubmitChanges();
          // and done
        scope.Complete();
      }
    }
    catch (Exception ex)
    {
       LoggerClient.Log(ex);
       response.Message = "It didn't save anything.";
    }
  }
}
Run Code Online (Sandbox Code Playgroud)