Невозможно откатить транзакцию с Entity Framework - PullRequest
2 голосов
/ 16 ноября 2009

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

Я сделал простой пример, чтобы воспроизвести проблему. У меня есть база данных только с одной таблицей под названием «Tabella», и таблица имеет два поля: «ID» - это автоматически сгенерированное целое число, а «Valore» - это целое число с ограничением «Уникальное». Затем я пытаюсь запустить этот код:

using (TransactionScope scope = new TransactionScope())
{
    Db1Container db1 = new Db1Container();

    try
    {
        db1.AddToTabella(new Tabella()
        {
            Valore = 1
        });
        db1.SaveChanges();
    }
    catch { }

    try
    {
        db1.AddToTabella(new Tabella()
        {
            Valore = 1
        });
        db1.SaveChanges(); //Unique constraint is violated here and an exception is thrown
    }
    catch { }

    try
    {
        db1.AddToTabella(new Tabella()
        {
            Valore = 2
        });
        db1.SaveChanges();
    }
    catch { }

    //scope.Complete(); //NEVER called
}   //here everything should be rolled back

Теперь, если я загляну в базу данных, она не должна содержать записей, потому что транзакция должна откатиться, вместо этого я нахожу две записи !!!! Один с Valore = 1 и один с Valore = 2. Я что-то упустил? Похоже, что второй вызов метода SaveChanges откатывает свои собственные изменения и «удаляет» транзакцию, затем третий вызов SaveChanges фиксирует изменения первой и третьей вставки (на данный момент это похоже на то, что транзакция не существует).

Я также пытался использовать метод SaveChanges (false) (даже без вызова метода AcceptAllChanges), но безуспешно: у меня такое же поведение.

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

Может ли кто-нибудь помочь мне с этим? Это похоже на "ошибку", и это вызывает у меня действительно большую головную боль ...

Ответы [ 2 ]

0 голосов
/ 01 февраля 2011

Это немного поздно для первоначального вопроса, но, возможно, это кому-то поможет.

Этот код должен работать с .net / ef 4 и sql server 2008 R2.

using (TransactionScope scope = new TransactionScope())
{
    Db1Container db1 = new Db1Container();

    try
    {
        db1.AddToTabella(new Tabella()
        {
            Valore = 1
        });
        db1.SaveChanges();

        db1.AddToTabella(new Tabella()
        {
            Valore = 1
        });
        db1.SaveChanges(); //Unique constraint is violated here and an exception is thrown

        //if we get here then there were no errors thrown on previous SaveChanges() 
        //calls and we can complete the transaction with no rollback
        scope.Complete();

    }
    catch (Exception)
    {
        //do nothing
    }

}
0 голосов
/ 16 ноября 2009

Вы уверены, что scope.Complete() никогда не вызывается? Если вы catch{} все исключения, код продолжит работу и будет достигнут оператор Complete. Вместо этого вы должны, например, разрешить исключению распространяться и перехватывать его на более высоком уровне.

...