Подтвердить что ты не робот

Как использовать транзакции с платформой Entity Framework?

Если у вас есть такой код:

Something something = new Something();
BlahEntities b = new BlahEntities()    
b.AddToSomethingSet(something);
b.SaveChanges();

как выполнить это добавление внутри транзакции?

4b9b3361

Ответ 1

Вы можете поместить свой код в область транзакций

using(TransactionScope scope = new TransactionScope())
{
    // Your code
    scope.Complete(); //  To commit.
}

TransactionScope находится в пространстве имен System.Transactions, которое находится в сборке с тем же именем (которое вам может потребоваться добавить вручную в ваш проект).

Ответ 2

ObjectContext имеет свойство соединения, которое можно использовать для управления транзакциями.

using (var context = new BlahEntities())
using (var tx = context.BeginTransaction())
{
    // do db stuff here...
    tx.Commit();
}

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

public static DbTransaction BeginTransaction(this ObjectContext context)
{
    if (context.Connection.State != ConnectionState.Open)
    {
        context.Connection.Open();
    }
    return context.Connection.BeginTransaction();
}

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

Ответ 3

Я знаю, что для LINQ to SQL контекст данных создаст транзакцию для SubmitChanges(), если нет существующей внешней транзакции (TransactionScope - это "окружающая" транзакция). Я не видел, чтобы это было документировано для LINQ для Entities, но я видел поведение, чтобы предположить, что оно верно и для Entity Framework.

Итак, если вы используете один SubmitChanges() (L2SQL) или SaveChanges() (Linq to Entities) для всех связанных изменений, вы должны быть в порядке, не используя TransactionScope. Вам понадобится TransactionScope, когда

  • Сохранение нескольких изменений с несколькими параметрами SubmitChanges/SaveChanges для одной транзакции.
  • Обновление нескольких источников данных в рамках одной транзакции (например, поставщик SQL-компонентов Linq и ASP.NET).
  • Вызов других методов, которые могут выполнять собственные обновления.

У меня были проблемы с вложенными TransactionScopes. Они должны работать, и простые тестовые примеры работают, но когда я попадаю в производственный код, "внутренняя" транзакция, похоже, является тем же объектом, что и внешняя транзакция. Симптомы включают ошибки, которые либо "совершены транзакцией, вы не можете использовать эту транзакцию больше", либо "этот объект транзакции уже удален". Ошибки возникают во внешней транзакции после выполнения внутренней транзакции.

Ответ 4

using System.Transactions;

using (TransactionScope scope = new TransactionScope())
{
    try
    {
        using(DataContext contextObject = new DataContext(ConnectionString))
        {
            contextObject.Connection.Open();
            // First SaveChange method.
            contextObject.SaveChanges();

            // Second SaveChange method.
            contextObject.SaveChanges();
            //--continue to nth save changes

            // If all execution successful
            scope.Complete();   
       }
    }
    catch(Exception ex)
    {
        // If any exception is caught, roll back the entire transaction and end the scope.
        scope.Dispose();
    }
    finally
    {
        // Close the opened connection
        if (contextObject.Connection.State == ConnectionState.Open)
        {
            contextObject.Connection.Close();
        }
    }
}

Найдите приведенную ниже ссылку для подробного объяснения https://msdn.microsoft.com/en-us/data/dn456843.aspx

Ответ 5

Во всех версиях Entity Framework всякий раз, когда вы выполняете SaveChanges() для вставки, обновления или удаления в базе данных, среда будет переносить эту операцию в транзакцию. Эта транзакция длится достаточно долго, чтобы выполнить операцию, а затем завершается. Когда вы выполняете другую такую ​​операцию, запускается новая транзакция. Для новой версии платформы Entity Framework: 6.0 +

Подробнее здесь: EntityFramework и транзакция