简体   繁体   English

如何避免在LINQ 2 SQL中升级为MSDTC

[英]How to avoid escalating to MSDTC in linq 2 sql

I have following situation : 我有以下情况:

  • application uses 2 databases 应用程序使用2个数据库
  • at some point, I need to use a transactionscope: 在某些时候,我需要使用一个transactionscope:

    insert record table A database X 插入记录表A数据库X

    insert record table C database Y 插入记录表C数据库Y

    submitchanges 提交变更

    insert record table B database X (one of the fields of B has the value of the primary key id of A that's why I need to call submitchanges) 插入记录表B数据库X(B的字段之一具有A的主键ID的值,这就是为什么我需要调用Submitchanges的原因)

    submitchanges 提交变更

    A & B must both be successfull, or fail together. A和B必须都成功,否则必须一起失败。 C doesn't matter. C没关系。 Insert on C does trigger the error MSDTC is nog available. 在C上插入确实会触发错误MSDTC可用。 But I don't want C to be part of the transaction ( for whatever reason ) I know that normally when they would be a relationship between A and B, the value (FKid) would be filled automatically, but I can not use FK relationship in this case. 但是我不希望C成为事务的一部分(无论出于何种原因),我知道通常当它们成为A和B之间的关系时,值(FKid)会自动填充,但是我不能使用FK关系在这种情况下。 (I guess there is no way of getting the id of a into b without using FK?) (我想如果不使用FK,就无法将a的ID转换为b?)

    I tried to specify enlist=false on the connectionstring of Y only, or even on both X and Y but I still get the error. 我尝试仅在Y的连接字符串上指定enlist = false,甚至在X和Y上都指定了enlist = false,但仍然收到错误。

MSDTC is the distributed transaction coordinator. MSDTC是分布式事务处理协调器。 When you attempt to update multiple databases within a transaction, the transaction will be escalated to MSDTC. 当您尝试更新事务中的多个数据库时,该事务将升级为MSDTC。 MSDTC must be enabled on the database server(s) and the client, I believe. 我相信必须在数据库服务器和客户端上启用MSDTC。 If you want to avoid this escalation, you'll need to have two separate transactions (using two separate connections), one for database X and one for database Y. 如果要避免这种升级,则需要具有两个单独的事务(使用两个单独的连接),一个事务用于数据库X,一个事务用于数据库Y。

When a transaction is promoted from a local transaction to a distributed transaction is in my opinion not always easy to know, and I have experienced places where I would expect it to be a local transaction, where it has been promoted to a distributed transaction, requiring DTC. 在我看来,将交易从本地交易提升为分布式交易并不总是那么容易,并且我在很多地方都曾希望将其视为本地交易,并将其提升为分布式交易,这需要DTC。

However, explicitly running the insert into database Y in a different transaction could solve the issue. 但是,在另一个事务中显式地将插入项运行到数据库Y中可以解决此问题。 You can then explicitly specify a transaction with TransactionScope.Suppress or TransactionScope.RequiresNew : 然后,您可以使用TransactionScope.SuppressTransactionScope.RequiresNew显式指定一个TransactionScope.RequiresNew

http://msdn.microsoft.com/en-us/library/system.transactions.transactionscopeoption.aspx http://msdn.microsoft.com/zh-CN/library/system.transactions.transactionscopeoption.aspx

// Update table A in database X
// ...


using(TransactionScope scope = new TransactionScope(
          TransactionScopeOption.RequiresNew
    ))
{
   // Update table C in database Y
   ...
   scope.Complete();
}

// Update table B in database X

However, ask yourself, is the insert into table C on database Y totally independent on the first insert in table A in database X? 但是,问自己,数据库Y中对表C的插入是否完全独立于数据库X中对表A的第一个插入? If not, what if the insert into table B in database X fails, is the insert into table C on database Y still valid? 如果不是,如果在数据库X的表B中插入失败,怎么办?在数据库Y的表C中插入仍然有效? Or might you end up with inconsistent data? 还是可能导致数据不一致? And, if so, does it matter enough for you to bring DTC into the soup? 而且,如果是这样,将DTC放入汤中是否足够重要?

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

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