Sql server 2008 TransactionScope问题-我如何防止DTC卷入其中?

Sql server 2008 TransactionScope问题-我如何防止DTC卷入其中?,sql-server-2008,transactionscope,msdtc,sqlconnection,Sql Server 2008,Transactionscope,Msdtc,Sqlconnection,(我知道围绕DTC和促进交易的情况对我们这些不知情的人来说可能有点神秘,但让我向你展示一下我的公司是如何做的,如果你能告诉我DTC介入的原因,如果可能的话,我能做些什么来避免它,我将不胜感激。) 我有运行在ASP.Net Web服务器上的代码。我们有一个数据库,SQL 2008 我们的数据访问代码如下所示——我们有一个数据访问层,它为SQLConnections和SQLCommands使用包装器对象。典型用法如下所示: void method1() { objDataObject = n

(我知道围绕DTC和促进交易的情况对我们这些不知情的人来说可能有点神秘,但让我向你展示一下我的公司是如何做的,如果你能告诉我DTC介入的原因,如果可能的话,我能做些什么来避免它,我将不胜感激。)

我有运行在ASP.Net Web服务器上的代码。我们有一个数据库,SQL 2008

我们的数据访问代码如下所示——我们有一个数据访问层,它为SQLConnections和SQLCommands使用包装器对象。典型用法如下所示:

void method1()
{
    objDataObject = new DataAccessLayer();
    objDataObject.Connection = SomeConnectionMethod();
    SqlCommand objCommand = DataAccessUtils.CreateCommand(SomeStoredProc);

//create some SqlParameters, add them to the objCommand, etc....

objDataObject.BeginTransaction(IsolationLevel.ReadCommitted);
objDataObject.ExecuteNonQuery(objCommand);
objDataObject.CommitTransaction();
objDataObject.CloseConnection();
}
事实上,围绕SqlClient、SqlConnection等的包装非常薄。我想在一个事务中运行几个存储的过程,而包装类不允许我访问SqlTransaction,因此我无法将它从一个组件传递到下一个组件。这导致我使用TransactionScope:

using (TransactionScope tx1 = new TransactionScope(TransactionScope.RequiresNew))
{
  method1();
  method2();
  method3();
  tx1.Complete();
}
当我这样做的时候,DTC就会被卷入其中,不幸的是,我们的Web服务器在MSDTC设置中没有启用“允许远程客户端”——让它允许这将是一场斗争


我很想避免卷入其中,但我能做到吗?我可以在methods1-3()中省去事务调用,让TransactionScope来解决所有问题吗?

SomeConnectionMethod()的作用是什么?如果在
method1()
method2()
method3()
中没有返回相同的连接,那么您就有了一个分布式事务。因此,DTC将参与协调该交易


因此,您必须在
SomeConnectionMethod()
中返回相同的连接,以防止DTC参与您的事务。

SomeConnectionMethod()做什么?如果在
method1()
method2()
method3()
中没有返回相同的连接,那么您就有了一个分布式事务。因此,DTC将参与协调该交易


因此,您必须在
SomeConnectionMethod()
中返回相同的连接,以防止DTC参与您的事务。

它不起作用的原因:

我认为,即使您共享相同的连接(如larryq所建议的),如果不涉及DTC,它也不会起作用

您需要一个事务作用域来包装这些方法:

  • 方法1
    • 开始训练
    • 提交传输
  • 方法2
    • 开始训练
    • 提交传输
  • 方法3
    • 开始训练
    • 提交传输
在每个方法中,您开始并提交。如果method3出现问题,您希望回滚所有内容,包括method1和Method2中已提交的事务。 要做到这一点,您需要一个涵盖所有3种方法的DTC事务

如果我错了,请纠正我,但我认为只有在方法内部不开始和提交事务时,才可以使用TransactionScope并避免使用DTC

它是如何工作的:

您真的需要在begin和commit中使用事务吗? 你不能做一些像:

using (var scope = new TransactionScope(TransactionScopeOption.Required)) {
   objDataObject.ExecuteNonQuery(objCommand);
}
范围Required而不是RequiredNew使用现有事务(如果已经存在)


如果我做错了什么,请随时纠正我

为什么不起作用:

我认为,即使您共享相同的连接(如larryq所建议的),如果不涉及DTC,它也不会起作用

您需要一个事务作用域来包装这些方法:

  • 方法1
    • 开始训练
    • 提交传输
  • 方法2
    • 开始训练
    • 提交传输
  • 方法3
    • 开始训练
    • 提交传输
在每个方法中,您开始并提交。如果method3出现问题,您希望回滚所有内容,包括method1和Method2中已提交的事务。 要做到这一点,您需要一个涵盖所有3种方法的DTC事务

如果我错了,请纠正我,但我认为只有在方法内部不开始和提交事务时,才可以使用TransactionScope并避免使用DTC

它是如何工作的:

您真的需要在begin和commit中使用事务吗? 你不能做一些像:

using (var scope = new TransactionScope(TransactionScopeOption.Required)) {
   objDataObject.ExecuteNonQuery(objCommand);
}
范围Required而不是RequiredNew使用现有事务(如果已经存在)


如果我做错了什么,请随时纠正我

谢谢。我很担心这个。SomeConnectionMethod()是一种实用方法,每次调用它时都会创建一个新连接。我无法更改这一点,不幸的是,继承自的类objDataObject没有其连接对象公共或可作为属性获取,因此我无法与其他objDataObjects共享它。听起来我在这方面运气不好。谢谢。我很担心这个。SomeConnectionMethod()是一种实用方法,每次调用它时都会创建一个新连接。我无法更改这一点,不幸的是,继承自的类objDataObject没有其连接对象公共或可作为属性获取,因此我无法与其他objDataObjects共享它。听起来我在这个方法上运气不好。