Linq to sql同一事务中的多个数据上下文 [英] Linq to sql multiple data context in same transaction

查看:122
本文介绍了Linq to sql同一事务中的多个数据上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在一个项目中,我有多个存储库来从中获取数据 不同的表.我所有的存储库都是独立的,它们创建新的dataContext,向表中添加行并应用Submit changes命令.现在,如果在我的服务中,存在一种情况,我必须将数据插入到多个表中,但是应该在一个事务中发生.我可以使用TrnasctionScope的东西实现这一点,但是那需要相同的dataContext.当我使用StrucutreMap创建对象时,无法获得相同的数据上下文,因此事务失败.

I am working on a project Where I have multiple reposetories to fetch data from differnt tables. All my repositories are independent, they create new dataContext, Add row to table and apply submit changes command. Now if in my service, there is a situation where I have to insert data into multiple tables, but it should happen in one transaction. I can achieve that using TrnasctionScope stuff, but thats needs same dataContext. As I am using StrucutreMap to create my objects, I cant get same data context, so my transaction fails.

这是我的物品.

interface IConnection
{
 MyDataContext GetContext();
}

public class Connection : IConnection
{

   public MyDataContext GetContext()
   {
    return new MyDataContext();
   }

} 

interface IRepositryA
{
  int SaveDataA(objectA a);
}

public class RepositoryA : IRepositryA
{
     public int SaveDataA(objectA a)
     {
        var context = objectFactory.GetInstance<IConnection>().GetContext();   
        context.TableA.InsertOnSubmit(a);
        context.SubmitChanges();

        return a.ID;
     }
}

interface IRepositryB
{
   int SaveDataA(objectB b);
}

public class RepositoryA : IRepositryB
{
     public int SaveDataB(objectB b)
     {

        var context = objectFactory.GetInstance<IConnection>().GetContext();   
        context.TableB.InsertOnSubmit(b);
        context.SubmitChanges();
        return b.ID;
     }
}

现在在我的服务层中,我称他们为

Now in my Service layer I have call them as

public MyServiceClass ()
 {
 public SaveAll(ObjectA a, ObjectB b)
 {

             using (TransactionScope trn);
            {
                ObjectFactory.GetInstance<IRepositryA>().SaveDataA(a);
                b.FkeyID = a.ID;
                ObjectFactory.GetInstance<IRepositryB>().SaveDataB(b);

                trn.complete();   
            }

  }
}

如何将相同的数据上下文传递给两个不同的存储库. 我选择,我认为是在每个存储库中创建一个重载方法,该方法接受IDataContext参数,如下所示.

How will I pass same data context to two differnt repositories. I option, I thought was creating one overloaded method in each repository which Accepts IDataContext parameter as given below.

interface IRepositryA
{
  int SaveDataA(objectA a);
  int SaveDataA(IConnection connection, objectA a);

}

public class RepositoryA : IRepositryA
{
     public int SaveDataA(objectA a)
     {
        var connection = objectFactory.GetInstance<IConnection>();   

        return SaveData(connection, a);
     }

     public int SaveDataA(IConnection connection, objectA a)
     {
        var context = connection.GetContext();   
        context.TableA.InsertOnSubmit(a);
        context.SubmitChanges();

        return a.ID;
     }

}

interface IRepositryB
{
   int SaveDataA(objectB b);
   int SaveDataA(IConnection connection, objectB b);

}

public class RepositoryA : IRepositryB
{
     public int SaveDataB(objectB b)
     {
        var connection = objectFactory.GetInstance<IConnection>();   
        return SaveData(connection, b);
     }

     public int SaveDataA(IConnection connection, objectB b)
     {
        var context = connection.GetContext();   
        context.TableB.InsertOnSubmit(b);
        context.SubmitChanges();

        return b.ID;
     }
}

在我的服务层中,我将其实现为

and in my service layer, I would implement it as

public MyServiceClass ()
 {
 public SaveAll(ObjectA a, ObjectB b)
 {
            IConnection connection= ObjectFactory.GetInstance<IConnection>();
            using (TransactionScope trn);
            {
                ObjectFactory.GetInstance<IRepositryA>().SaveDataA(connection,a);
                b.FkeyID = a.ID;
                ObjectFactory.GetInstance<IRepositryB>().SaveDataB(connection,b);

                trn.complete();   
            }

  }
}


第二个想法是,如果我能以某种方式配置DataContext以返回相同的连接 当我调用GetContext方法时.因此所有存储库将使用相同的连接.但我认为这将使连接始终保持活动状态.我希望此连接仅在此SaveAll方法期间可用.


Second thought I have is, if somehow I can configure DataContext to return same connection when I call GetContext method. so all repositories will use same connection. But I feel that will keep the connection alive all the time. I want this connection to available during the time of this SaveAll method only.

您的帮助将不胜感激.提前致谢.

Your help will be appritiated. Thanks in advance.

欢呼 Parminder

Cheers Parminder

推荐答案

TransactionScope可以与多个DataContext一起使用,但是一旦涉及多个连接,该事务就会升级为MSDTC/XA/分布式事务.为此,您需要在运行代码的系统和数据库服务器上都运行MSDTC.

TransactionScope can be used with multiple DataContexts, but as soon as more than one connection is involved the transaction is escalated to a MSDTC/XA/distributed transaction. For that to work you need to have MSDTC running on both the system where you code runs and on the database server.

或者,如果您在transactionscope中创建显式连接并将其传递到数据上下文,则可以避免升级到分布式事务.这样,TransactionScope将不会升级为分布式事务,并且不会依赖MSDTC ...

Alternatively, you can avoid escalation to a distributed transaction if you create an explicit connection within the transactionscope and pass that to your datacontexts; that way the TransactionScope will not escalate to a distributed transaction, and won't rely on MSDTC...

这篇关于Linq to sql同一事务中的多个数据上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆