简体   繁体   English

如何在EF4中为多个ObjectContext实现单个SQL事务

[英]How to implement single SQL transaction for multiple ObjectContexts in EF4

I have a fairly big database with tables created for different business modules. 我有一个很大的数据库,其中包含为不同业务模块创建的表。

We decided to create different edmx-files for different modules respectively. 我们决定分别为不同的模块创建不同的edmx文件。

However, how can I prevent the usage of MSDTC when trying to implement a TransactionScope for a logical action that will incur writing to multiple tables in different edmx? 但是,当尝试为将导致写入不同edmx中的多个表的逻辑操作实现TransactionScope时,如何防止使用MSDTC? Again, the underlying database is the same, I wouldn't want to use MSDTC for this scenario. 同样,基础数据库是相同的,在这种情况下,我不想使用MSDTC。

Is there any way to pass in an opened SQL connection with active transaction? 有什么方法可以通过活动事务传递打开的SQL连接?

Thanks for help in advance. 预先感谢您的帮助。

Regards, William 问候,威廉

TransactionScope enlists the MSDTC when the databases are different and/or the connection strings are different. 当数据库不同和/或连接字符串不同时, TransactionScope征集MSDTC。

Rick Strahl has a great article on this (his perspective is LINQ to SQL, but it's applicable to EF). Rick Strahl在这方面有一篇很棒的文章 (他的观点是LINQ to SQL,但它适用于EF)。 The money paragraphs: 钱款:

TransactionScope is a high level Transaction wrapper that makes it real easy to wrap any code into a transaction without having to track transactions manually. TransactionScope是高级事务包装器,它使将任何代码包装到事务中变得非常容易,而不必手动跟踪事务。 Traditionally TransactionScope was a .NET wrapper around the Distributed Transaction Coordinator (DTC) but it's functionality has expanded somewhat. 传统上,TransactionScope是围绕.NET的分布式事务处理协调器(DTC)的包装程序,但其功能有所扩展。 One concern is that the DTC is rather expensive in terms of resource usage and it requires that the DTC service is actually running on the machine (yet another service which is especially bothersome on a client installation). 一个令人担忧的问题是,就资源使用而言,DTC相当昂贵,并且它要求DTC服务实际上在计算机上运行(但另一项服务在客户端安装上特别麻烦)。

However, recent updates to TransactionScope and the SQL Server Client drivers make it possible to use TransactionScope class and the ease of use it provides without requiring DTC as long as you are running against a single database and with a single consistent connection string. 但是,只要对单个数据库和单个一致的连接字符串运行,就可以对TransactionScope和SQL Server Client驱动程序进行最新更新,从而可以使用TransactionScope类及其提供的易用性而无需DTC。 In the example above, since the transaction works with a single instance of a DataContext, the transaction actually works without involving DTC. 在上面的示例中,由于事务处理使用DataContext的单个实例,因此事务处理实际上不涉及DTC。 This is in SQL Server 2008. 这是在SQL Server 2008中。

See also this SO question/answer where I found the link to Rick's blog. 另请参阅此SO问题/答案 ,我在其中找到了Rick博客的链接。

So if you're connecting to the same database and are using the same connection string, the DTC should not be involved. 因此,如果您要连接到相同的数据库并使用相同的连接字符串,则不应涉及DTC。

thanks for all replies above! 感谢您上面的所有回复!

by the way, just managed to find a solution which is to use EntityConnection and EntityTransaction explicitly. 顺便说一句,只是设法找到一个解决方案,即显式使用EntityConnection和EntityTransaction。 A sample is like this: 示例如下:

    string theSqlConnStr = "data source=TheSource;initial catalog=TheCatalog;persist security info=True;user id=TheUserId;password=ThePassword";

    EntityConnectionStringBuilder theEntyConnectionBuilder = new EntityConnectionStringBuilder();
    theEntyConnectionBuilder.Provider = "System.Data.SqlClient";
    theEntyConnectionBuilder.ProviderConnectionString = theConnectionString;
    theEntyConnectionBuilder.Metadata = @"res://*/";

    using (EntityConnection theConnection = new EntityConnection(theEntyConnectionBuilder.ToString()))
    {
        theConnection.Open();
        theET = null;

        try
        {
            theET = theConnection.BeginTransaction();

            DataEntities1 DE1 = new DataEntities1(theConnection);
            //DE1 do somethings...

            DataEntities2 DE2 = new DataEntities2(theConnection);
            //DE2 do somethings...

            DataEntities3 DE3 = new DataEntities3(theConnection);
            //DE3 do somethings...

            theET.Commit();
        }
        catch (Exception ex)
        {
            if (theET != null) { theET.Rollback(); }
        }
        finally
        {
            theConnection.Close();
        }
    }

with explicit use of EntityConnection & EntityTransaction, I can achieve the sharing of single connection and transaction for multiple ObjectContexts for a single database, yet without the need to incur the usage of MSDTC. 通过显式使用EntityConnection和EntityTransaction,我可以为单个数据库实现多个ObjectContext的单个连接和事务的共享,而无需使用MSDTC。

Hope this info is helpful. 希望此信息对您有所帮助。 Gd luck!! 祝你好运!!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM