在我们的项目中,我们使用TransactionScope来确保我们的数据访问层在事务中执行它的操作。我们的目标是不要求我们的最终用户机器上启用MSDTC服务。
问题是,在我们一半的开发人员机器上,我们可以在禁用MSDTC的情况下运行。另一半必须启用它,否则他们将获得“MSDTC on服务器不可用“错误信息。
以下为示例代码,在试图升级的机器上,它尝试在第二个连接中升级.Open()(当时并没有打开其他连接)
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();
}
以下是它工作机器的一些信息:
不针对开发人员:
所有机器为了寻找问题都已经完全用Microsoft Update提供的所有软件进行了修补。
MSDN事务升级页面声明,以下条件将导致事务升级到DTC:
我重新调查了每个人的SQL Server版本 - “Dev 3”实际上有SQL2008,“Dev 4”实际上是SQL2005。 由于数据的这种变化,我已经确定找到了问题。 我们的SQL2008开发人员没有遇到这个问题,因为SQL2008包含SQL2005所没有的功能。
由于我们支持SQL 2005,所以不能像以前那样使用TransactionScope。如果我们想要使用TransactionScope,我们需要在周围传递一个SqlConnection对象...这在SqlConnection很难被传递的情况下是有问题的。它只是看起来像是全局-SqlConnection实例。
SQL 2008:
SQL 2005:
通过使用单个SqlConnection
将SQL2005升级到DTC
using (TransactionScope transactionScope = new TransactionScope()) {
using (SqlConnection connection = new SqlConnection(connectionString)) {
connection.Open();
connection.Close();
connection.Open(); // escalates to DTC
}
}
因此我可以理解是否每个调用SqlConnection.Open()
都从连接池中获取。
如果在打开之前使用SqlTableAdapter来阻止该连接,SqlTableAdapter将打开并关闭连接,有效地为你完成事务。
因此,基本上,为了成功地使用SQL2005的TransactionScope,你需要有某种全局连接对象,从第一个TransactionScope的点一直保持开放,直到不再需要它为止。除了一个全局连接对象的代码,首先打开连接并关闭它,这与尽可能晚打开连接的逻辑以及尽快关闭连接的逻辑是不一致的。
发布于 2018-02-26 09:46:54
SQL2008可以在TransactionScope
中使用多个SQLConnections
,而不需要升级,但是如果同时打开多个连接的话会导致多个“物理”TCP连接,因此需要升级。
有一些开发人员使用SQL 2005,而其他开发人员则使用SQL 2008。
关于这个问题最明显的解释是,使用SQL 2008的开发人员没有升级。
发布于 2018-02-26 10:42:23
发布于 2018-02-26 11:43:34
http://msdn.microsoft.com/en-us/Library/ms 172070.aspx
SQLServer 2008中的可提升事务
在.NET Framework和SQL Server 2005的2.0版中,在TransactionScope中打开第二个连接会自动将事务提升为完整的分布式事务,即使两个连接都使用相同的连接字符串。 在这种情况下,分布式事务会增加不必要的开销,从而降低性能。 从SQL Server 2008和.NET Framework 3.5版开始,如果在关闭上一个事务后在事务中打开了另一个连接,则本地事务将不再提升为分布式事务。 如果你已经在使用连接池并参与事务处理,则不需要更改代码。
但是我没有办法解释为什么Dev 3:Windows 7 x64、SQL 2005成功和Dev 4:Windows 7 x64失败。
https://stackoverflow.com/questions/-100007436
复制相似问题