Obsługa błędów zatwierdzania transakcji

Uwaga

Tylko platforma EF6.1 — funkcje, interfejsy API itp. omówione na tej stronie zostały wprowadzone w programie Entity Framework 6.1. Jeśli korzystasz ze starszej wersji, niektóre lub wszystkie podane informacje nie mają zastosowania.

W ramach wersji 6.1 wprowadzamy nową funkcję odporności połączenia dla platformy EF: możliwość automatycznego wykrywania i odzyskiwania po przejściowych błędach połączenia wpływa na potwierdzenie zatwierdzeń transakcji. Pełne szczegóły scenariusza są najlepiej opisane we wpisie w blogu SQL Database Połączenie ivity i Problem z idempotencją. Podsumowując, scenariusz polega na tym, że w przypadku zgłoszenia wyjątku podczas zatwierdzania transakcji istnieją dwie możliwe przyczyny:

  1. Zatwierdzenie transakcji nie powiodło się na serwerze
  2. Zatwierdzenie transakcji powiodło się na serwerze, ale problem z łącznością uniemożliwił powiadomienie o powodzeniu dotarcie do klienta

W pierwszej sytuacji aplikacja lub użytkownik może ponowić próbę wykonania operacji, ale gdy druga sytuacja wystąpi, należy unikać ponownych prób, a aplikacja może zostać odzyskana automatycznie. Wyzwaniem jest to, że bez możliwości wykrywania, jaki był rzeczywisty powód zgłoszenia wyjątku podczas zatwierdzania, aplikacja nie może wybrać odpowiedniego przebiegu akcji. Nowa funkcja w programie EF 6.1 umożliwia programowi EF dwukrotne sprawdzenie bazy danych, jeśli transakcja zakończyła się pomyślnie i w sposób przezroczysty podejmie odpowiednie działania.

Korzystanie z funkcji

Aby włączyć tę funkcję, należy dołączyć wywołanie metody SetTransactionHandler w konstruktorze elementu DbConfiguration. Jeśli nie znasz funkcji DbConfiguration, zobacz Konfiguracja oparta na kodzie. Tej funkcji można używać w połączeniu z automatycznymi ponownymi próbami wprowadzonymi w programie EF6, co pomaga w sytuacji, w której transakcja rzeczywiście nie mogła zatwierdzić na serwerze z powodu błędu przejściowego:

using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.SqlServer;

public class MyConfiguration : DbConfiguration  
{
  public MyConfiguration()  
  {  
    SetTransactionHandler(SqlProviderServices.ProviderInvariantName, () => new CommitFailureHandler());  
    SetExecutionStrategy(SqlProviderServices.ProviderInvariantName, () => new SqlAzureExecutionStrategy());  
  }  
}

Jak są śledzone transakcje

Po włączeniu funkcji program EF automatycznie doda nową tabelę do bazy danych o nazwie __Transactions. Nowy wiersz jest wstawiany w tej tabeli za każdym razem, gdy transakcja jest tworzona przez program EF, a ten wiersz jest sprawdzany pod kątem istnienia, jeśli podczas zatwierdzania wystąpi błąd transakcji.

Mimo że program EF będzie starał się przycinać wiersze z tabeli, gdy nie są już potrzebne, tabela może rosnąć, jeśli aplikacja kończy się przedwcześnie i z tego powodu może być konieczne ręczne przeczyszczenie tabeli w niektórych przypadkach.

Jak obsługiwać błędy zatwierdzania z poprzednimi wersjami

Przed ef 6.1 nie było mechanizmu obsługi błędów zatwierdzania w produkcie EF. Istnieje kilka sposobów radzenia sobie z tą sytuacją, które można zastosować do poprzednich wersji programu EF6:

  • Opcja 1 — nic nie rób

    Prawdopodobieństwo niepowodzenia połączenia podczas zatwierdzania transakcji jest niskie, więc może być akceptowalne, aby aplikacja mogła po prostu zakończyć się niepowodzeniem, jeśli ten warunek rzeczywiście wystąpi.

  • Opcja 2 — resetowanie stanu przy użyciu bazy danych

    1. Odrzuć bieżący tekst DbContext
    2. Tworzenie nowej bazy danych DbContext i przywracanie stanu aplikacji z bazy danych
    3. Poinformuj użytkownika, że ostatnia operacja mogła nie zostać ukończona pomyślnie
  • Opcja 3 — ręczne śledzenie transakcji

    1. Dodaj nieśledzenia tabeli do bazy danych używanej do śledzenia stanu transakcji.
    2. Wstaw wiersz do tabeli na początku każdej transakcji.
    3. Jeśli połączenie nie powiedzie się podczas zatwierdzania, sprawdź obecność odpowiedniego wiersza w bazie danych.
      • Jeśli wiersz jest obecny, kontynuuj normalnie, ponieważ transakcja została zatwierdzona pomyślnie
      • Jeśli wiersz jest nieobecny, użyj strategii wykonywania, aby ponowić próbę wykonania bieżącej operacji.
    4. Jeśli zatwierdzenie zakończy się pomyślnie, usuń odpowiedni wiersz, aby uniknąć wzrostu tabeli.

Ten wpis w blogu zawiera przykładowy kod umożliwiający wykonanie tego zadania w Usługi SQL Azure.