TransactionScope и Transaction в LINQ to SQL - PullRequest
75 голосов
/ 12 февраля 2009

В чем различия между классическим шаблоном транзакций в 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
    {
    }
}

Ответы [ 5 ]

74 голосов
/ 12 февраля 2009

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

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

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

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

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

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

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

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

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

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

35 голосов
/ 12 февраля 2009

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

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

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

21 голосов
/ 05 октября 2011

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

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

7 голосов
/ 18 мая 2012

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

4 голосов
/ 12 февраля 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...