Вопрос по entity-framework, transactions – Как использовать транзакции с Entity Framework?

27

Когда у вас есть такой код:

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

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

Ваш Ответ

5   ответов
9

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

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

  1. Saving multiple changes with multiple SubmitChanges/SaveChanges for one transaction.
  2. Updating multiple data sources within one transaction (e.g., Linq and ASP.NET membership SQL provider).
  3. Calling other methods that may do their own updates.

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

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded pupeno
26

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

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

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

Error: User Rate Limit Exceededmsdn.microsoft.com/en-us/library/…
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
0

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

Подробнее здесь:EntityFramework и Transaction

1
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.
            context,Object.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

55

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 будет продвигаться к распределенной транзакции, которая может не потребоваться.

Error: User Rate Limit Exceededcontext.Connection.BeginTransaction.
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded

Похожие вопросы