TransactionScope的自动升级为MSDTC某些机器上? [英] TransactionScope automatically escalating to MSDTC on some machines?

查看:215
本文介绍了TransactionScope的自动升级为MSDTC某些机器上?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我们的项目中,我们使用的TransactionScope的,以确保我们的数据访问层执行它的行为在一个事务中。我们的目标到的不是的要求MSDTC服务我们的最终用户的机器被激活。

In our project we're using TransactionScope's to ensure our data access layer performs it's actions in a transaction. We're aiming to not require the MSDTC service to be enabled on our end-user's machines.

麻烦的是,在我们一半的开发者的机器,我们可以MSDTC禁用运行。另一半必须有它启用或他们得到的MSDTC在[SERVER]不可用的错误消息。

Trouble is, on half of our developers machines, we can run with MSDTC disabled. The other half must have it enabled or they get the "MSDTC on [SERVER] is unavailable" error message.

这真的让我抓我的头,并有我认真考虑回滚到基于ADO.NET的交易对象家纺的TransactionScope样的解决方案。这看似疯狂 - 同样的code,工程(并且不升级)的一半,我们的开发的确实升级上的其他开发人员的

It's really got me scratching my head and has me seriously considering rolling back to a home-spun TransactionScope-like solution based on ADO.NET transaction objects. It's seemingly insane - the same code that works (and does not escalate) on half of our developer's does escalate on the other developer's.

我希望向 http://stackoverflow.com/questions/506733/ 一个更好的答案,但遗憾的是它不吨。

I was hoping for a better answer to http://stackoverflow.com/questions/506733/ but unfortunately it doesn't.

下面是code进行采样位,这将造成麻烦,上尽量升级机器,它会尝试升级第二connection.Open()(是的,没有其他的连接在开放时间)。

Here's a sample bit of code that will cause the trouble, on the machines that try to escalate, it tries to escalate on the second connection.Open() (and yes, there is no other connection open at the time.)

using (TransactionScope transactionScope = new TransactionScope() {
   using (SqlConnection connection = new SqlConnection(_ConStr)) {
      using (SqlCommand command = connection.CreateCommand()) {
         // prep the command
         connection.Open();
         using (SqlDataReader reader = command.ExecuteReader()) {
            // use the reader
            connection.Close();
         }
      }
   }

   // Do other stuff here that may or may not involve enlisting 
   // in the ambient transaction

   using (SqlConnection connection = new SqlConnection(_ConStr)) {
      using (SqlCommand command = connection.CreateCommand()) {
         // prep the command
         connection.Open();  // Throws "MSDTC on [SERVER] is unavailable" on some...

         // gets here on only half of the developer machines.
      }
      connection.Close();
   }

   transactionScope.Complete();
}

我们真的挖,并试图弄清楚这一点。下面是机器上的一些信息,它适用于:

We've really dug in and tried to figure this out. Here's some info on the machines that it works on:

  • 开发1:Windows 7的64位SQL2008
  • 开发2:Windows 7中的x86 SQL2008
  • 开发3:Windows 7的64位<打击> SQL2005 SQL2008
  • Dev 1: Windows 7 x64 SQL2008
  • Dev 2: Windows 7 x86 SQL2008
  • Dev 3: Windows 7 x64 SQL2005 SQL2008

开发它不工作:

  • 开发4:Windows 7的64,<击> SQL2008 SQL2005
  • 开发5:Windows Vista的X86,SQL2005
  • 开发6:Windows XP的X86,SQL2005
  • 在我的家用电脑:Windows Vista家庭premium,86,SQL2005
  • Dev 4: Windows 7 x64, SQL2008 SQL2005
  • Dev 5: Windows Vista x86, SQL2005
  • Dev 6: Windows XP X86, SQL2005
  • My Home PC : Windows Vista Home Premium, x86, SQL2005

我要补充一点,所有的机器,在努力追捕的问题,都得到了充分的一切,是可从Microsoft Update补丁。

I should add that all machines, in an effort to hunt down the problem, have been fully patched with everything that's available from Microsoft Update.

  • <一个href="http://social.msdn.microsoft.com/forums/en-US/windowstransactionsprogramming/thread/a5462509-8d6d-4828-aefa-a197456081d3/">http://social.msdn.microsoft.com/forums/en-US/windowstransactionsprogramming/thread/a5462509-8d6d-4828-aefa-a197456081d3/描述了一个类似的问题......早在2006年!
  • <一个href="http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope%28VS.80%29.aspx">http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope%28VS.80%29.aspx - 阅读code样品,它清楚地表明嵌套第二个连接(到第二个SQL服务器,实际上)将升级为DTC。 我们不这样做,我们的code 的 - 我们没有使用不同的SQL服务器,也不是不同的连接字符串,我们也没有嵌套的辅助连接开放 - 的不应该有升级到DTC
  • <一个href="http://davidhayden.com/blog/dave/archive/2005/12/09/2615.aspx">http://davidhayden.com/blog/dave/archive/2005/12/09/2615.aspx (2005年)谈论如何升级到DTC连接到SQL2000时,总是会发生。我们使用SQL2005 / 2008
  • <一个href="http://msdn.microsoft.com/en-us/library/ms229978.aspx">http://msdn.microsoft.com/en-us/library/ms229978.aspx MSDN上的事务升级。
  • http://social.msdn.microsoft.com/forums/en-US/windowstransactionsprogramming/thread/a5462509-8d6d-4828-aefa-a197456081d3/ describes a similar problem...back in 2006!
  • http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope%28VS.80%29.aspx - read that code sample, it clearly demonstrates a nested-second connection (to a second SQL server, actually) which will escalate to DTC. We are not doing this in our code - we're not using different SQL servers, nor different connection strings, nor do we have nested secondary connections opening - there should not be escalation to DTC.
  • http://davidhayden.com/blog/dave/archive/2005/12/09/2615.aspx (from 2005) talks about how escalation to DTC will always happen when connecting to SQL2000. We're using SQL2005/2008
  • http://msdn.microsoft.com/en-us/library/ms229978.aspx MSDN on transaction escalation.

这MSDN事务升级页的规定,以下情况将导致事务升级到DTC:

That MSDN transaction-escalation page states that the following conditions will cause a transaction to escalate to DTC:

  1. 在不支持单相通知至少有一个持久的资源在事务中登记。
  2. 支持单相通知至少两种持久资源在事务中登记。例如,招募具有不会导致事务的单一连接被提升。但是,当你打开第二个连接到数据库,使数据库中登记的System.Transactions的基础设施,检测到它在事务中的第二个持久的资源,并将其升级到MSDTC事务。
  3. 的请求为元帅的交易,以不​​同的应用程序域或不同的进程被调用。例如,跨应用程序域边界的事务对象的序列化。本次交易对象编组按值,这意味着任何试图通过它跨应用程序域边界(即使是在同一个进程),导致交易对象的序列化。您可以通过在远程方法,需要一个交易作为一个参数,也可以尝试访问远程事务性服务的组件调用传递交易对象。这种序列化的交易对象和结果的升级,因为当一个事务跨应用程序域的序列化。它是被分布和本地事务管理器已不再适当。

我们没有遇到#3。 #2是不会发生,因为只有过一次连接,而且它也是一个持久的资源。有没有什么办法,#1可能会发生?一些SQL2005 / 8的配置,导致它不支持单相的通知?

We're not experiencing #3. #2 is not happening because there is only ever one connection at a time, and it's also to a single 'durable resource'. Is there any way that #1 could be happening? Some SQL2005/8 configuration that causes it to not support single-phase notifications?

重新调查,个人,每个人的SQL Server版本 - 开发3实际上有SQL2008,而开发4其实是SQL2005。这会教我再也不会相信我的同事。 ;)这一变化的数据,因为,我是pretty的肯定,我们已经发现了我们的问题。我们SQL2008开发者没有遇到的问题,因为SQL2008有真棒丰富金额包含了SQL2005没有。

Re-investigated, personally, everyone's SQL Server versions - "Dev 3" actually has SQL2008, and "Dev 4" is actually SQL2005. That'll teach me to never trust my coworkers again. ;) Because of this change in data, I'm pretty sure we've found our problem. Our SQL2008 developers weren't experiencing the problem because SQL2008 has copious amounts of awesome included that SQL2005 does not have.

这也告诉我,因为我们将要支持SQL2005,我们不能使用的TransactionScope像我们一直在,如果我们要使用的TransactionScope我们将需要被周围路过一个SqlConnection对象...这似乎是有问题的,其中的SqlConnection不容易被身边经过的情况......它只是闻全球的SqlConnection实例。皮尤!

It also tells me that because we're going to be supporting SQL2005 that we can't use TransactionScope like we have been, and if we want to use TransactionScope we're going to need to be passing a single SqlConnection object around...which seems problematic in situations where the SqlConnection can't easily be passed around...it just smells of global-SqlConnection instance. Pew!

只是在这里澄清在这个问题:

Just to clarify up here in the question:

SQL2008:

  • 允许在一个单一的TransactionScope多个连接(这表现在上面的示例code。)
  • 买​​者#1:如果这些多个SqlConnections是嵌套的,即,两个或更多个SqlConnections被打开的同时,将TransactionScope的立即升级到DTC。
  • 在告诫#2:如果一个额外的SqlConnection打开一个不同的耐用资源的(即:不同的SQL Server,),它会立刻升级为DTC
  • Allows multiple connections within a single TransactionScope (as demonstrated in the above sample code.)
  • Caveat #1: If those multiple SqlConnections are nested, that is, two or more SqlConnections are opened at the same time, TransactionScope will immediately escalate to DTC.
  • Caveat #2: If an additional SqlConnection is opened to a different 'durable resource' (ie: a different SQL Server,) it will immediately escalate to DTC

SQL2005:

  • 不允许在一个单一的TransactionScope多个连接,期。当/如果第二次的SqlConnection打开它就会升级。

在做混乱这个问题更加<打击>的利益有用的,只是为了更清晰起见,这里是你如何能得到SQL2005升级到DTC使用的 的SqlConnection

In the interest of making this question even more of a mess useful, and just for more clarity's sake, here's how you can get SQL2005 to escalate to DTC with a single SqlConnection:

using (TransactionScope transactionScope = new TransactionScope()) {
   using (SqlConnection connection = new SqlConnection(connectionString)) {
      connection.Open();
      connection.Close();
      connection.Open(); // escalates to DTC
   }
}

这似乎只是打破我,但我想我可以理解,如果每次调用在SQLConnection.open()从连接池中抓。

This just seems broken to me, but I guess I can understand if every call to SqlConnection.Open() is grabbing from the connection pool.

为什么会发生这种情况有关系吗?的哦,如果您使用针对该连接的SqlTableAdapter它打开之前,该SqlTableAdapter将打开和关闭连接,有效地完成交易,因为你现在还不能重新打开它。

"Why might this happen, though?" Well, if you use a SqlTableAdapter against that connection before it's opened, the SqlTableAdapter will open and close the connection, effectively finishing the transaction for you because you now can't re-open it.

所以,基本上,为了成功地使用的TransactionScope与SQL2005你需要有某种形式的全球连接对象是仍然从第一的TransactionScope点开被实例化,直到它不再需要。除了code-气味全局连接对象,首先打开连接,并关闭它最后是有分歧对打开连接尽可能晚地,并尽快关闭它的逻辑。

So, basically, in order to successfully use TransactionScope with SQL2005 you need to have some sort of global connection object that remains open from the point of the first TransactionScope is instantiated until it's no longer needed. Besides the code-smell of a global connection object, opening the connection first and closing it last is at odds against the logic of opening a connection as late as possible and closing it as soon as possible.

推荐答案

SQL2008可以在的TransactionScope 的SQLConnection 取值C>没有升级,所提供的连接不同时开放的,这将导致多个物理的TCP连接,因此需要升级。

SQL2008 can use multiple SQLConnections in a TransactionScope without escalating, provided the connections are not open at the same time, which would result in multiple "physical" TCP connections and thus require escalation.

我看你的一些开发人员SQL2005等SQL2008。你确定你已经正确识别哪些是不断升级的,哪些不是?

I see some of your developers have SQL2005 and others SQL2008. Are you sure you have correctly identified which ones are escalating and which not?

最明显的解释是开发商与SQL 2008是那些没有升级。

The most obvious explanation would be that developers with SQL 2008 are the ones that aren't escalating.

这篇关于TransactionScope的自动升级为MSDTC某些机器上?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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