4

我有一个相当大的数据库,其中包含为不同业务模块创建的表。

我们决定分别为不同的模块创建不同的 edmx 文件。

但是,在尝试为将导致写入不同 edmx 中的多个表的逻辑操作实现 TransactionScope 时,如何防止使用 MSDTC?同样,底层数据库是相同的,我不想在这种情况下使用 MSDTC。

有没有办法通过活动事务传递打开的 SQL 连接?

提前感谢您的帮助。

问候,威廉

4

2 回答 2

2

TransactionScope enlists the MSDTC when the databases are different and/or the connection strings are different.

Rick Strahl has a great article on this (his perspective is LINQ to SQL, but it's applicable to 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. Traditionally TransactionScope was a .NET wrapper around the Distributed Transaction Coordinator (DTC) but it’s functionality has expanded somewhat. 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).

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. In the example above, since the transaction works with a single instance of a DataContext, the transaction actually works without involving DTC. This is in SQL Server 2008.

See also this SO question/answer where I found the link to Rick's blog.

So if you're connecting to the same database and are using the same connection string, the DTC should not be involved.

于 2012-10-17T03:04:54.110 回答
0

感谢以上所有回复!

顺便说一句,刚刚设法找到一个解决方案,即明确使用 EntityConnection 和 EntityTransaction 。一个样本是这样的:

    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();
        }
    }

通过显式使用 EntityConnection 和 EntityTransaction,我可以实现单个数据库的多个 ObjectContext 的单个连接和事务的共享,而无需使用 MSDTC。

希望这些信息有帮助。祝你好运!!

于 2012-10-19T06:00:33.343 回答