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

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

问题描述

我正在做一个项目,我有多个存储库可以从中获取数据不同的表.我所有的存储库都是独立的,它们创建新的 dataContext,将行添加到表并应用提交更改命令.现在,如果在我的服务中,有一种情况我必须将数据插入到多个表中,但它应该发生在一个事务中.我可以使用 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.

干杯提醒

推荐答案

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 就不会升级为分布式事务,也不会依赖 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天全站免登陆