Programavimas

Kaip tvarkyti sutapimų konfliktus „Entity Framework“

Duomenų vientisumui ir nuoseklumui palaikyti, kai keli vartotojai vienu metu naudojasi tuo pačiu ištekliu, gali būti naudojamas lygiagretumas. Lygiagretumo pažeidimai gali įvykti, kai turite tarpusavyje susijusių operacijų, t. Y. Operacijų, kurios yra priklausomos viena nuo kitos ir bando pasiekti tą patį šaltinį.

Lygiagretumo konfliktų tvarkymas „Entity Framework“

Dabar supraskime, kaip kiekviena iš šių strategijų veikia „Entity Framework“. Pesimistiškai sutampant, kai konkretus įrašas yra atnaujinamas, visi kiti tuo pačiu įrašo atnaujinimai bus sulaikyti, kol dabartinė operacija bus baigta ir valdymas bus atsisakytas, kad kitos kartu vykstančios operacijos galėtų tęstis. Optimistišku lygiagretumo režimu paskutinis išsaugotas įrašas „laimi“. Šiuo režimu daroma prielaida, kad išteklių konfliktai dėl tuo pačiu metu pasiekiamų bendrų išteklių yra mažai tikėtini, bet ne neįmanomi.

Beje, pagal numatytuosius nustatymus „Entity Framework“ palaiko optimistinį sutapimą. „Entity Framework“ nepalaiko pesimistinio sutapimo iš anksto. Dabar supraskime, kaip „Entity Framework“ sprendžia sutapimo konfliktus, kai dirba optimistiškai (numatytasis režimas).

Dirbdami optimistišku lygiagretumo apdorojimo režimu, paprastai norėtumėte išsaugoti duomenis savo duomenų bazėje, darant prielaidą, kad duomenys nesikeitė nuo tada, kai buvo įkelti į atmintį. Atminkite, kad bandant išsaugoti duomenų bazės pakeitimus naudojant „SaveChanges“ metodą duomenų konteksto egzemplioriuje, bus išmestas „DbUpdateConcurrencyException“. Dabar supraskime, kaip mes galime tai išspręsti.

Norėdami patikrinti, ar nėra lygiagretumo pažeidimų, galite įtraukti lauką į savo subjektų klasę ir pažymėti jį naudodami „Timeestamp“ atributą. Žr. Toliau pateiktą subjektų klasę.

visuomenės klasės Autorius

   {

public Int32 Id {get; rinkinys; }

public string FirstName {get; rinkinys; }

vieša eilutė Pavardė {get; rinkinys; }

viešoji eilutė Adresas {get; rinkinys; }

[Laiko antspaudas]

viešasis baitas [] RowVersion {get; rinkinys; }

   }

Dabar „Entity Framework“ palaiko du lygiagretumo režimus: Nėra ir Fiksuotas. Pirmasis reiškia, kad atnaujinant objektą nebūtų atliekami lygiagretumo patikrinimai, antrasis reiškia, kad vykdant WHERE sąlygas tuo metu, kai atnaujinami ar ištrinami duomenys, bus atsižvelgiama į pradinę turto vertę. Jei turite ypatybę, kuri pažymėta naudojant laiko žymą, sutapimo režimas laikomas fiksuotu, o tai savo ruožtu reiškia, kad pradinė nuosavybės vertė bus atsižvelgta į WHERE sąlygą apie bet kokio konkretaus subjekto duomenų atnaujinimus ar ištrynimus.

Norėdami išspręsti optimistinius sutapimo konfliktus, galite pasinaudoti metodo Perkrauti pranašumais, kad atnaujintumėte dabartines objekto, esančio atmintyje, reikšmes naujausiomis duomenų bazės vertėmis. Perkrovę atnaujintus duomenis, galite pabandyti dar kartą išsaugoti savo objektą duomenų bazėje. Šis kodo fragmentas parodo, kaip tai galima pasiekti.

naudojant (var dbContext = naujas IDBDataContext ())

{

Autorius autorius = dbContext.Authors.Find (12);

autorius.Adresas = "Hyderabad, Telengana, INDIJA";

bandyti

         {

dbContext.SaveChanges ();

         }

sugavimas (DbUpdateConcurrencyException ex)

         {

pvz., Įrašai.Vienas (). Perkrauti ();

dbContext.SaveChanges ();

         }

}

Atminkite, kad galite panaudoti „DbUpdateConcurrencyException“ egzemplioriaus įrašų metodą, kad gautumėte „DbEntityEntry“ egzempliorių sąrašą, atitinkantį objektus, kurių nepavyko atnaujinti, kai buvo iškviestas metodas „SaveChanges“, kad subjektai išliktų duomenų bazėje.

Dabar ką tik aptartas požiūris dažnai vadinamas „saugomais laimėjimais“ arba „duomenų bazių laimėjimais“, nes subjekte esantys duomenys yra perrašomi duomenų bazėje esančiais duomenimis. Taip pat galite vadovautis kitu požiūriu, vadinamu „klientas laimi“. Pagal šią strategiją duomenys iš duomenų bazės gaunami norint užpildyti objektą. Iš esmės duomenys, gauti iš pagrindinės duomenų bazės, nustatomi kaip pirminės subjekto vertės. Šis kodo fragmentas parodo, kaip tai galima pasiekti.

bandyti

{

dbContext.SaveChanges ();

}

sugavimas (DbUpdateConcurrencyException ex)

{

var duomenys = ex.Entries.Single ();

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

}

Taip pat galite patikrinti, ar objektą, kurį bandote atnaujinti, jau ištrynė kitas vartotojas, ar jį jau atnaujino kitas vartotojas. Šis kodo fragmentas parodo, kaip tai padaryti.

sugavimas (DbUpdateConcurrencyException ex)

{

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

jei (subjektas == nulis)

   {

Console.WriteLine („Atnaujinamą objektą jau ištrino kitas vartotojas ...“);

   }

Kitas

   {

Console.WriteLine ("Atnaujinamą objektą jau atnaujino kitas vartotojas ...");

   }

}

Jei jūsų duomenų bazės lentelėje nėra laiko žymos stulpelio ar eilutės versijos, galite pasinaudoti ConcurrencyCheck atributo pranašumais, kad aptiktumėte sutapimo konfliktus, kai naudojate Entity Framework. Štai kaip naudojama ši nuosavybė.

[Lentelė („Autoriai“]

visuomenės klasės Autorius

{

viešasis autorius () {}

[Raktas]

public int Id {get; rinkinys; }

[ConcurrencyCheck]

public string FirstName {get; rinkinys; }

vieša eilutė Pavardė {get; rinkinys; }

viešoji eilutė Adresas {get; rinkinys; }

}

Tai darydamas, SQL serveris automatiškai įtraukia AuthorName vykdydamas naujinimo arba ištrynimo sakinius duomenų bazėje.