Існує 2 основних види операцій; транзакції з підключенням та зовнішні транзакції. Трансакція підключення (наприклад, SqlTransaction) прив’язана безпосередньо до db-з'єднання (наприклад, SqlConnection), що означає, що вам доведеться продовжувати передачу з'єднання навколо - OK у деяких випадках, але не дозволяє "створювати / використовувати / випускати" використання та не дозволяє працювати з перехресними db. Приклад (відформатований для простору):
using (IDbTransaction tran = conn.BeginTransaction()) {
try {
// your code
tran.Commit();
} catch {
tran.Rollback();
throw;
}
}
Не надто безладний, але обмежений нашим зв'язком "conn". Якщо ми хочемо закликати до різних методів, тепер нам потрібно пройти "conn" навколо.
Альтернатива - зовнішня транзакція; Новий в .NET 2.0 об'єкт TransactionScope (System.Transaction.dll) дозволяє використовувати для ряду операцій (відповідні провайдери автоматично зараховуються до зовнішньої транзакції). Це дозволяє легко ретро вписатись у існуючий (не транзакційний) код та поговорити з декількома постачальниками (хоча DTC буде залучатися, якщо ви поговорите з більш ніж одним).
Наприклад:
using(TransactionScope tran = new TransactionScope()) {
CallAMethodThatDoesSomeWork();
CallAMethodThatDoesSomeMoreWork();
tran.Complete();
}
Зауважте тут, що два способи можуть обробляти свої власні з'єднання (відкривати / використовувати / закривати / розпоряджатися), але вони мовчки стануть частиною зовнішньої транзакції, без того, щоб нам нічого проходити.
Якщо у вашому коді помилки, Dispose () буде викликано без завершення (), тому він буде повернутий назад. Очікується, що очікується гніздування тощо. Підтримується, хоча ви не можете відкатати внутрішню транзакцію, але зовнішню транзакцію не завершено: якщо хтось незадоволений, транзакція припиняється.
Інша перевага TransactionScope полягає в тому, що він не прив’язаний лише до баз даних; будь-який постачальник, обізнаний з транзакціями, може використовувати його. WCF, наприклад. Або є навіть деякі об'єктні моделі TransactionScope (тобто .NET-класи з можливістю відкату - можливо, простіше, ніж пам'ять, хоча я ніколи не використовував такий підхід).
Загалом, дуже, дуже корисний об’єкт.
Деякі застереження:
- На SQL Server 2000 TransactionScope негайно перейде до DTC; це виправлено в SQL Server 2005 і вище, він може використовувати LTM (набагато менше накладних витрат), поки ви не поговорите з двома джерелами тощо, коли він буде підвищений до DTC.
- Існує глюк, який означає, що вам може знадобитися підключити рядок з'єднання