Как использовать транзакции с текстом данных - PullRequest
17 голосов
/ 15 мая 2009

Можно ли использовать транзакции с текстом данных, чтобы я мог откатить состояние контекста после ошибки? И если да, то как это работает?

Ответы [ 5 ]

18 голосов
/ 15 мая 2009

Я использую их в тестировании постоянно:)

try
{
  dc.Connection.Open();
  dc.Transaction = dc.Connection.BeginTransaction();

  dc.SubmitChanges();
}
finally
{
  dc.Transaction.Rollback();
}

UPDATE

Это будет ВСЕГДА откат после свершившегося факта. Я использую это в тестировании.

15 голосов
/ 15 мая 2009

DataContext по умолчанию выбирает внешнюю транзакцию, так что это просто вопрос обеспечения наличия транзакции в области действия. Детали становятся главной проблемой:

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

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

using (var trans = new TransactionScope(
                           TransactionScopeOption.Required,
                           new TransactionOptions {
                               IsolationLevel = IsolationLevel.ReadCommitted
                           },
                           EnterpriseServicesInteropOption.Automatic)) {
    // Perform operations using your DC, including submitting changes

    if (allOK) {
        trans.Complete();
    }
}

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

12 голосов
/ 08 апреля 2011

Это не так просто, как метод TransactionScope, но, насколько я понимаю, это «правильный» способ сделать это для LINQ-to-SQL. Не требуется никаких ссылок на System.Transactions.

dataContext.Connection.Open();
using (dataContext.Transaction = dataContext.Connection.BeginTransaction())
{
    dataContext.SubmitChanges();

    if (allOK)
    {
        dataContext.Transaction.Commit();
    }
    else
    {
        dataContext.Transaction.RollBack();
    }
}

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

10 голосов
/ 15 мая 2009

Примерно так, наверное:

try
{
    using (TransactionScope scope = new TransactionScope())
    {
        //Do some stuff

        //Submit changes, use ConflictMode to specify what to do
        context.SubmitChanges(ConflictMode.ContinueOnConflict);

        scope.Complete();
    }
}
catch (ChangeConflictException cce)
{
        //Exception, as the scope was not completed it will rollback
}
0 голосов
/ 23 июля 2013

Это что-то вроде этого:

using (YourDatacontext m_DB = new YourDatacontext())
using (TransactionScope tran = new TransactionScope())
{
   try
   {
      //make here the changes
      m_DB.SubmitChanges();
      tran.Complete();
   }
   catch (Exception ex)
   {
       Transaction.Current.Rollback();
   }
}
...