C # TransactionScope - L2E - PullRequest
       27

C # TransactionScope - L2E

5 голосов
/ 02 марта 2010

Стоит ли использовать System.Transactions.TransactionScope на Linq to Entities?

В документации MS говорится, что все вызовы SQL в ObjectContext.SaveChanges () внутренне объединены в одну транзакцию.

У нас есть 1 соединение с базой данных, то есть локальная база данных SQLite в файловой системе. Мы просто хотим убедиться, что все наши операции с базой данных являются атомарными. Нужен ли нам TransactionScope? т.е. когда мы призываем к некоторому удалению, обновлению, вставке и т. д., мы хотим, чтобы все они произошли или вообще не произошли.

Ответы [ 3 ]

3 голосов
/ 02 марта 2010

Джон, нет, вам не нужно использовать TransactionScope. Оптимистичный параллелизм обрабатывается автоматически Linq. Пример кода в предоставленной вами ссылке объясняет, что вам не нужно откатывать транзакции самостоятельно. Я бы использовал тот же код, что и в примере:

    try
    {
        // Try to save changes, which may cause a conflict.
        int num = context.SaveChanges();
        Console.WriteLine("No conflicts. " +
            num.ToString() + " updates saved.");
    }
    catch (OptimisticConcurrencyException)
    {
        // Resolve the concurrency conflict by refreshing the 
        // object context before re-saving changes. 
        context.Refresh(RefreshMode.ClientWins, orders);

        // Save changes.
        context.SaveChanges();
        Console.WriteLine("OptimisticConcurrencyException "
        + "handled and changes saved");
    }

Обратите внимание на обновление, повторное сохранение, которое решает вашу проблему. Вы можете проверить это, выдав исключение из блока try.

С наилучшими пожеланиями

1 голос
/ 02 марта 2010

Если вы хотите включить более чем ObjectContext.SaveChanges в одну транзакцию (например, чтение данных, которые вы собираетесь изменить, а также изменения), тогда вам нужно использовать TransactionScope.

0 голосов
/ 02 марта 2010

Вы можете использовать следующий код, если вам нужно сделать то, что говорит Ричард (хотя это кажется довольно маловероятным):

TransactionManager transactionManager = null;

try
{
    bool isBorrowedTransaction = ConnectionScope.Current.HasTransaction;
    transactionManager = ConnectionScope.ValidateOrCreateTransaction(true);

    //MANY SAVES

    if (!isBorrowedTransaction && transactionManager != null && transactionManager.IsOpen)
        transactionManager.Commit();
}
catch (Exception ex)
{
    if (transactionManager != null && transactionManager.IsOpen)
        transactionManager.Rollback();
    log.Error("An unexpected Exception occurred", ex);
    throw;
}
...