3. Entity Framework da parallelizm. Entity Framework bilan ishlashda, biz bir vaqtning o‘zida bir nechta foydalanuvchilar bir xil ma’lumotlar to‘plamiga kirish imkoniga ega bo‘lsa va bu ma’lumotlarni o‘zgartirishi mumkin bo‘lsa, unda parallelizm muammosi yuzaga keladi. Misol uchun, ikkita foydalanuvchi bir-biridan mustaqil ravishda bir xil ob’ektni tahrirlashni boshladi. Ob’ektni birinchi foydalanuvchi tomonidan saqlangandan so‘ng, ikkinchi foydalanuvchi allaqachon ahamiyatsiz bo‘lgan ma’lumotlar bilan ishlaydi.
Misolni ko‘rib chiqaylik. Masalan, ilovada ASP.NET MVC ning standart o‘zgartirish harakat bor:
1
2
3
4
5
6
7
8
9
10
11
12
|
public ActionResult Edit(int id)
{
Person p = db.People.Find(id);
return View(p);
}
[HttpPost]
public ActionResult Edit(Person p)
{
db.Entry(p).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
|
Ushbu kod mukammal ishlayotgan bo‘lsada, lekin agar har ikkala foydalanuvchi bir vaqtning o‘zida o‘zgartirish uchun bir xil ob’ektni ochsa, o‘zgartirilgan ob’ektni birinchi foydalanuvchi saqlagandan so‘ng, ikkinchi foydalanuvchi allaqachon eskirgan ma’lumotlar bilan ishlaydi.
Ushbu muammoni hal qilish uchun Entity Framework nima taklif qiladi?
Birinchidan, parallelizmning ikki turi bor: optimistik va pisimistik.
Pessimistik parallelizm (pessimistic concurrency) bilan ma’lumotlar bazasiga kirish cheklovlari qo‘llaniladi. Misol uchun, qatorlar faqat o‘qish yoki yangilash uchun e’lon qilinadi. Pessimistik parallelizm ma’lumotlar bazasi darajasida ishlashni nazarda tutadi va kirish huquqlarini kuzatish va boshqarish uchun murakkab dasturiy mantiqni yaratishni o‘z ichiga oladi. Pessimistik parallelizm uchun Entity Framework da hech qanday yordam yo‘q.
Optimistik parallelizm (optimistic concurrency) bilan, yuqoridagi holatda bo‘lgani kabi, turli foydalanuvchilar tomonidan ma’lumotlarga parallel kirish muammosiga ruxsat beriladi. Entity Framework ning optimistik parallelizmni hal qilish uchun o‘z metodlari bor.
Ba’zi metodlar modelda [Timestamp] xususiyati bilan maxsus xususiyatni e’lon qilish orqali jadvaldagi satrning modifikatsiyasini kuzatadi. Misol uchun:
1
2
3
4
5
6
7
8
9
|
using System.ComponentModel.DataAnnotations;
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
[Timestamp]
public byte[] RowVersion { get; set; }
}
|
Timestamp xususiyati, RowVersion xususiyatining qiymati, yangilanish va o‘chirish uchun buyruqlar bazasiga yuborilganda, yaratilgan Entity Framework SQL ifodasi bilan kiritiladi. Xususiyatning bir turi sifatida baytlar massivi ishlatiladi.
Bundan tashqari, o‘zgartirish ko‘rinishida yangi xususiyat qiymatini saqlash uchun yashirin maydonni qo‘shishingiz kerak:
1
|
@Html.HiddenFor(model => model.RowVersion)
|
Endi, agar ikki foydalanuvchi bir vaqtning o‘zida bir xil modelni tahrirlashni boshlasalar, birinchi foydalanuvchi tomonidan modelni saqlagandan so‘ng, ikkinchi foydalanuvchi DbUpdateConcurrencyException istisnosini oladi (System.Data.Entity.Infrastructure nomlari maydonida joylashgan), bu esa shunga mos ravishda qayta ishlanishi kerak:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
[HttpPost]
public ActionResult Edit(Person p)
{
try
{
db.Entry(p).State = EntityState.Modified;
db.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
ViewBag.Error = "Объект ранее уже был изменен";
return View(p);
}
return RedirectToAction("Index");
}
|
Foydalanuvchini xato haqida bilish uchun, har qanday ko‘rinishda View.BagError ni o‘chirib qo‘ying. Endi bir xil ob’ektni bir vaqtda tahrirlash bilan, ikkinchi saqlash foydalanuvchisi xatoga yo‘l qo‘yadi va uning tahrirlashi ma’lumotlar bazasiga saqlanmaydi.
Do'stlaringiz bilan baham: |