TransactionScope vs Transaction в LINQ to SQL

Каковы различия между классическим шаблоном транзакций в LINQ to SQL, например:

using(var context = Domain.Instance.GetContext())
{
    try
    {
        context.Connection.Open();
        context.Transaction = context.Connection.BeginTransaction();
        /*code*/
        context.Transaction.Commit();
    }
    catch
    {
        context.Transaction.Rollback();
    }         
}

против объекта TransactionScope

using (var context = Domain.Instance.GetContext())
using (var scope = new TransactionScope())
{
    try
    {
        /*code*/
        scope.Complete();
    }
    catch
    {
    }
}

Ответ 1

Linq2SQL будет использовать неявную транзакцию. Если все ваши обновления выполняются в рамках одного Submit, вам может не понадобиться обрабатывать транзакцию самостоятельно.

Из документации (акцент мой):

Когда вы вызываете SubmitChanges, LINQ to SQL проверяет, включен ли вызов в транзакцию или если свойство Transaction (IDbTransaction) установлено на локальную транзакцию, начатую пользователем. Если он не находит ни одной транзакции, LINQ to SQL запускает локальную транзакцию (IDbTransaction) и использует ее для выполнения сгенерированных SQL-команд. Когда все команды SQL успешно завершены, LINQ to SQL фиксирует локальную транзакцию и возвращается.

Ответ 2

Следует отметить, что при использовании TransactionScope нет необходимости в конструкции try/catch, которую у вас есть. Вам просто нужно вызвать Complete в области действия, чтобы зафиксировать транзакцию при выходе из области.

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

При вызове BeginTransaction на DbConnection object, вы должны передать этот объект транзакции, если вы хотите выполнять другие операции в одной транзакции, но другим способом.

С TransactionScope, пока область существует, она будет обрабатывать все, что регистрируется с текущим Transaction в потоке, делая ваш код более чистым и более удобным.

Кроме того, у вас есть дополнительное преимущество в том, что вы можете использовать другие ресурсы, которые могут участвовать в транзакциях, а не только подключение к базе данных.

Следует отметить, что в ситуациях, когда вам нужно больше всего выжать из своих соединений и операций с базой данных, вы, возможно, не захотите использовать TransactionScope; даже против одной базы данных, вы запускаете возможность использования Координатора распределенных транзакций и превращения транзакции в распределенную транзакцию (даже для одного подключения к базе данных).

В этих случаях, в то время как muddying вверх по вашему дизайну, вы можете рассмотреть возможность передачи транзакции, специфичной для подключения.

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

Вы должны создать класс, который при построении создает ваш ресурс/увеличивает счетчик. Он также будет реализовывать IDisposable (в котором вы должны декретировать/освободить/зафиксировать/прервать, когда счетчик равен нулю) и сохранить счетчик в переменную с ThreadStaticAttribute, примененную к ней.

Это позволяет отделить управление транзакциями от логического кода и по-прежнему эффективно удерживать исключительный ресурс (вместо эскалации в распределенную транзакцию).

Ответ 3

Одно большое различие (урок усложняется) - TransactionScope использует MS DTC для управления транзакциями.

Если ваше приложение должно управлять только транзакцией базы данных и не задействованы никакие службы или удаленные вызовы, вы можете пропустить возможные проблемы, связанные с MS DTC, используя транзакцию, родную для баз данных (DbTransactions).

Ответ 4

Я считаю, что они принципиально те же, что класс TransactionScope будет взаимодействовать с базовым соединением ADO.NET для создания и фиксации транзакции или откат транзакции. Что класс TransactionScope был только что создан, чтобы работать с очистителем настойчивости ADO.NET.

Изменить: Разъяснение моего заявления относительно дополнение casperOne, это будет TransactionScope, который создаст транзакцию, и соединение затем увидит транзакция, созданная TransactionScope и использующая ее, поскольку она доступна для нее.

Ответ 5

TransactionScope обеспечивает унифицированное управление для всех менеджеров ресурсов (SQL-сервер, активный каталог, файловая система,...). Кроме того, можно написать собственный менеджер ресурсов: код, который определяет область транзакции, присоединяется к ней и работает точно так же, как SQL-сервер: совершает или отменяет изменения, как и другие участники транзакции. Я считал, что TransactionScope является основным и забыл родные транзакции MS SQL, пока не попал в огромную ловушку: WEB-версия Windows Server 2008 поставляется с ограниченной службой координаторов распределенных транзакций и областью транзакций только на одном компьютере. Приложение ASP.NET не будет работать в этой системе, если IIS и SQL-сервер будут установлены на разных компьютерах. Учтите, что большинство поставщиков общедоступных доменов поставляют версию Windows Server WEB и сервер SQL на отдельных серверах. Это означает, что вы должны работать с собственными транзакциями, используя явное управление транзакциями...