(我知道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全部解决这个问题吗?
答案 0 :(得分:1)
SomeConnectionMethod()
做什么?如果它未在method1()
,method2()
和method3()
中返回相同的连接,那么您将拥有分布式事务。所以DTC将参与协调这项交易。
因此,您必须在SomeConnectionMethod()
中返回相同的连接,以防止DTC涉及您的交易。
答案 1 :(得分:0)
为什么不起作用
我认为,即使您将共享相同的连接(如larryq所建议的那样),如果不涉及DTC也不会有效。
您希望事务范围包装这些方法:
在每个方法中,您开始并提交。如果在method3中出现问题,您想要回滚所有内容,包括方法1和2中已提交的事务。 要做到这一点,您需要一个跨越所有3种方法的DTC交易。
如果我错了,请纠正我,但我认为只有在方法内部没有开始和提交事务时,才能使用TransactionScope并避免使用DTC。
如何运作
你真的需要使用begin和commit的事务吗? 你不能做这样的事情:
using (var scope = new TransactionScope(TransactionScopeOption.Required)) {
objDataObject.ExecuteNonQuery(objCommand);
}
范围必需而不是 RequiredNew 使用现有交易(如果已存在)。
如果我出错了,请随时纠正我。