2009-12-12 1 views
0

(Я знаю, что обстоятельства, связанные с DTC, и продвижение транзакции могут быть немного загадочными для тех из нас, кто не знает, но позвольте мне показать вам, как моя компания делает что-то, и если вы можете сказать мне, почему DTC вовлекаясь, и, если возможно, что я могу сделать, чтобы этого избежать, я был бы благодарен.)Вопрос TransactionScope - как я могу заставить 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 settings-- получение ИТ допустить, что будет борьба.

Я хотел бы избежать использования DTC, но могу ли я это сделать? Могу ли я игнорировать транзакционные вызовы в методах1-3() и просто позволить TransactionScope все выяснить?

ответ

1

Что делает SomeConnectionMethod()? Если он не возвращает то же соединение в method1(), method2() и method3(), то у вас есть распределенная транзакция. Поэтому DTC будет задействован для координации этой транзакции.

Таким образом, вы должны вернуть такое же соединение в SomeConnectionMethod(), чтобы предотвратить использование DTC в транзакции.

+0

Спасибо. Я беспокоился об этом. SomeConnectionMethod() - это метод утилиты, который создает новое соединение каждый раз, когда он вызывается. Я не могу это изменить, и, к сожалению, класс objDataObject наследуется от не имеет своего объекта Connection public или get-able как свойство, поэтому я не могу поделиться им с другими объектами objDataObjects. Похоже, мне не повезло в этом подходе. – larryq

0

Почему это не работает:

Я думаю, даже если бы вы один и то же соединение (как это было предложено larryq), он не будет работать, не получая DTC участия.

Вы хотите объем сделки, чтобы обернуть эти методы:

  • method1
    • Begin Tran
    • COMMIT Tran
  • method2
    • Begin Tran
    • Commit Tran
  • method3
    • Begin Tran
    • Commit Tran

В каждом методе вы начинаете и фиксации. Если что-то пойдет не так в методе3, вы хотите отменить все, включая уже совершенные транзакции из метода1 & 2. Для этого вам нужна транзакция DTC, которая охватывает все 3 метода.

Исправьте меня, если я ошибаюсь, но я думаю, вы можете использовать TransactionScope и избегать использования DTC только в том случае, если вы не начинаете и не совершаете транзакции внутри методов.

Как это могло работать:

вам действительно нужно использовать транзакции с начала и совершить ли? не могли бы вы сделать что-то вроде:

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

The Scope Требуется вместо RequiredNew использует существующую транзакцию, если она уже существует.

Пожалуйста, не стесняйтесь исправить меня, если у меня что-то не так.

Смежные вопросы