TransactionScope问题 - 如何让DTC无法参与其中?

时间:2009-12-12 06:22:48

标签: sql-server-2008 transactionscope msdtc sqlconnection

(我知道DTC的情况和推销交易对于我们这些不知情的人来说可能有点神秘,但是让我告诉你我公司是怎么做的,如果你能告诉我为什么DTC正在参与,如果可能的话,我可以做些什么来避免它,我将不胜感激。)

我在ASP.Net网络服务器上运行代码。我们有一个数据库,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参与其中,不幸的是我们的网络服务器没有在MSDTC设置中启用“允许远程客户端” - 让IT允许这将是一场战斗。

我想避免DTC参与,但我可以这样做吗?我可以省去方法1-3()中的事务调用,然后让TransactionScope全部解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

SomeConnectionMethod()做什么?如果它未在method1()method2()method3()中返回相同的连接,那么您将拥有分布式事务。所以DTC将参与协调这项交易。

因此,您必须在SomeConnectionMethod()中返回相同的连接,以防止DTC涉及您的交易。

答案 1 :(得分:0)

为什么不起作用

我认为,即使您将共享相同的连接(如larryq所建议的那样),如果不涉及DTC也不会有效。

您希望事务范围包装这些方法:

  • 方法1
    • 开始Tran
    • 提交Tran
  • 方法2
    • 开始Tran
    • 提交Tran
  • 方法3
    • 开始Tran
    • 提交Tran

在每个方法中,您开始并提交。如果在method3中出现问题,您想要回滚所有内容,包括方法1和2中已提交的事务。 要做到这一点,您需要一个跨越所有3种方法的DTC交易

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

如何运作

你真的需要使用begin和commit的事务吗? 你不能做这样的事情:

using (var scope = new TransactionScope(TransactionScopeOption.Required)) {
   objDataObject.ExecuteNonQuery(objCommand);
}

范围必需而不是 RequiredNew 使用现有交易(如果已存在)。

如果我出错了,请随时纠正我。