2015-01-28 10 views
7

W mojej aplikacji ASP.NET MVC5 Identity 2, próbującej użyć transakcji, ale nie działa. Proszę zapoznać się z poniższym kodem transakcje nie działają. Jeśli var saveteacher = _teacherService.Create(aTeacher); nie wstawić pomyślnie, AspNetUsers nie wycofanie z bazy danych.Jak korzystać z transakcji w tożsamości ASP.NET MVC 2?

Kod:

using (var dataContext = new SchoolMSDbContext()) 
{ 
    using (var trans = dataContext.Database.BeginTransaction(IsolationLevel.ReadCommitted)) 
    { 
    try 
    { 
     var adminresult =await UserManager.CreateAsync(user, teacherViewModel.Password); 
     if (adminresult.Succeeded) 
     { 
     aTeacher.Id = user.Id; 
     var saveteacher = _teacherService.Create(aTeacher); 
     } 
     else 
     { 
     trans.Rollback(); 
     ModelState.AddModelError("", adminresult.Errors.First()); 
     return View(); 
     } 
     trans.Commit(); 
    } 
    catch (Exception ex) 
    { 
     trans.Rollback(); 
     Console.WriteLine(ex.InnerException); 
    } 
    } 
} 
+0

Wygląda na legit. Czy przejrzałeś kod w debugerze? Czy 'trans.Rollback()' kiedykolwiek wywołało błąd? – trailmax

+1

no :(ale catch throw Exception ex {"Walidacja nie powiodła się dla jednej lub więcej encji Zobacz więcej informacji na temat właściwości EntityValidationErrors."} Które zrobiłem dla testowania –

+0

skąd to jest wyrzucane? Masz 3 miejsca w tobie, że kod może rzucić ten wyjątek, wszystkie są zawijane w 'try-catch', ale robisz' Rollback' w haczyku.Czy to wycofanie nie jest wykonywane? – trailmax

Odpowiedz

6

Myślę, że problem może być z asynchronicznym rzeczy.

spróbuj utworzyć transakcję tak:

TransactionScope transaction = new TransactionScope(System.Transactions.TransactionScopeAsyncFlowOption.Enabled); 

(musisz dodać System.Transactions) do referencji.

Aby zatwierdzić transakcję, przejdź do transaction.Complete(), aby wycofać, wykonaj transaction.Dispose().

+1

Awesome! It Worked! Ale mam pytanie: Jeśli usunę asynchronizację, to mój poprzedni kod nie będzie działał. dlaczego?. Anyway aktualizuję mój kod, jak już powiedziałeś i teraz działa. Dzięki :) –

+2

Tożsamość domyślnie działa w asynchronizmie. A metody synchronizacji to tylko opakowania kodu asynchronicznego. Więc jeśli dodasz transakcje na wierzchu, pojawia się asynchroniczna natura. – trailmax

+0

Dzięki @trailmax twoje następująca instrukcja jest tak pomocna "Domyślnie tożsamość działa w asynchronizmie, a metody synchronizacji są tylko opakowaniami kodu asynchronicznego." –

1

Problem polega na tym, że tworzysz nowe wystąpienie SchoolMSDbContext, gdy powinieneś już uzyskać istniejące z HttpContext.

Przykład:

using (var dataContext = HttpContext.GetOwinContext().Get<ApplicationDbContext>()) 
    { 
     //... 
    } 
0

Upewnij _teacherService i UserManager używa tego samego DB kontekście. Nie trzeba tworzyć TransactionScope.