Programování

Jak řešit konflikty souběžnosti v Entity Framework

Zpracování souběžnosti lze použít k udržení integrity dat a konzistence dat, když více uživatelů přistupuje ke stejnému prostředku současně. K narušení souběžnosti může dojít, když máte vzájemně závislé transakce, tj. Transakce, které jsou navzájem závislé a pokusíte se získat přístup ke stejnému prostředku.

Zpracování konfliktů souběžnosti v Entity Framework

Pojďme nyní pochopit, jak každá z těchto strategií funguje v Entity Framework. V pesimistické souběžnosti se při aktualizaci konkrétního záznamu všechny ostatní souběžné aktualizace ve stejném záznamu pozastaví, dokud není aktuální operace dokončena a ovládací prvek se nevzdá zpět, aby mohly pokračovat další souběžné operace. V optimistickém režimu souběžnosti „vyhraje“ poslední uložený záznam. V tomto režimu se předpokládá, že konflikty prostředků v důsledku souběžných přístupů ke sdílenému prostředku jsou nepravděpodobné, ale nikoli nemožné.

Mimochodem, Entity Framework ve výchozím nastavení poskytuje podporu pro optimistickou souběžnost. Entity Framework neposkytuje podporu pesimistické souběžnosti ihned po vybalení z krabice. Pojďme nyní pochopit, jak Entity Framework řeší konflikty souběžnosti při práci v optimistické souběžnosti (výchozí režim).

Při práci s optimistickým režimem zpracování souběžnosti byste obvykle chtěli ukládat data do své databáze za předpokladu, že se data nezměnila od doby, kdy byla načtena do paměti. Všimněte si, že když se pokusíte uložit změny do databáze pomocí metody SaveChanges v instanci kontextu dat, bude vyvolána DbUpdateConcurrencyException. Pojďme nyní pochopit, jak to můžeme napravit.

Chcete-li zkontrolovat narušení souběžnosti, můžete zahrnout pole do své třídy entity a označit jej pomocí atributu Timestamp. Viz třída entit uvedená níže.

veřejná třída Autor

   {

public Int32 Id {get; soubor; }

public string FirstName {get; soubor; }

veřejný řetězec Příjmení {get; soubor; }

public string Adresa {get; soubor; }

[Časové razítko]

public byte [] RowVersion {get; soubor; }

   }

Nyní Entity Framework podporuje dva režimy souběžnosti: Žádný a Opravený. Zatímco první znamená, že by se při aktualizaci entity neprováděly žádné kontroly souběžnosti, druhá naznačuje, že původní hodnota vlastnosti bude brána v úvahu při provádění klauzulí WHERE v době, kdy jsou prováděny aktualizace nebo mazání dat. Pokud máte vlastnost, která je označena pomocí Timestamp, režim souběžnosti je považován za Fixed, což zase znamená, že původní hodnota vlastnosti by byla považována v klauzuli WHERE jakékoli aktualizace nebo odstranění dat pro danou entitu.

Chcete-li vyřešit optimistické konflikty souběžnosti, můžete využít metodu Reload k aktualizaci aktuálních hodnot ve vaší entitě, která se nachází v paměti s nedávnými hodnotami v databázi. Po opětovném načtení aktualizovaných dat se můžete pokusit znovu přetrvávat svoji entitu v databázi. Následující fragment kódu ukazuje, jak toho lze dosáhnout.

pomocí (var dbContext = nový IDBDataContext ())

{

Autor autor = dbContext.Authors.Find (12);

author.Address = "Hyderabad, Telengana, INDIE";

Snaž se

         {

dbContext.SaveChanges ();

         }

catch (DbUpdateConcurrencyException ex)

         {

např. Entries.Single (). Reload ();

dbContext.SaveChanges ();

         }

}

Všimněte si, že můžete využít Entries metodu v instanci DbUpdateConcurrencyException k načtení seznamu instancí DbEntityEntry odpovídajících entitám, které nemohly být aktualizovány, když byla volána metoda SaveChanges k přetrvávání entit do databáze.

Přístup, o kterém jsme právě hovořili, se nyní často nazývá „uložené výhry“ nebo „vyhraje databáze“, protože data obsažená v entitě jsou přepsána daty dostupnými v databázi. Můžete také použít jiný přístup zvaný „klient vyhrává“. V této strategii jsou načtena data z databáze k naplnění entity. V podstatě jsou data načtená z podkladové databáze nastavena jako původní hodnoty pro entitu. Následující fragment kódu ukazuje, jak toho lze dosáhnout.

Snaž se

{

dbContext.SaveChanges ();

}

catch (DbUpdateConcurrencyException ex)

{

var data = např. Entries.Single ();

data.OriginalValues.SetValues ​​(data.GetDatabaseValues ​​());

}

Můžete také zkontrolovat, zda entita, kterou se pokoušíte aktualizovat, již byla odstraněna jiným uživatelem nebo již byla aktualizována jiným uživatelem. Následující fragment kódu ukazuje, jak to můžete udělat.

catch (DbUpdateConcurrencyException ex)

{

var entity = ex.Entries.Single (). GetDatabaseValues ​​();

if (entity == null)

   {

Console.WriteLine ("Aktualizovaná entita je již odstraněna jiným uživatelem ...");

   }

jiný

   {

Console.WriteLine ("Aktualizovaná entita již byla aktualizována jiným uživatelem ...");

   }

}

Pokud vaše databázová tabulka nemá sloupec nebo verzi řádků s časovým razítkem, můžete využít výhod ConcurrencyCheck atributu ke zjištění konfliktů souběžnosti při použití Entity Framework. Zde je ukázáno, jak se tato vlastnost používá.

[Tabulka („Autoři“)

veřejná třída Autor

{

public Author () {}

[Klíč]

public int Id {get; soubor; }

[Kontrola souběžnosti]

public string FirstName {get; soubor; }

veřejný řetězec Příjmení {get; soubor; }

public string Adresa {get; soubor; }

}

Při tom by SQL Server automaticky zahrnoval AuthorName při provádění aktualizací nebo mazání příkazů v databázi.

$config[zx-auto] not found$config[zx-overlay] not found