Kerangka Kerja Entitas - Konkurensi
Setiap pengembang akses data menghadapi kesulitan saat menjawab pertanyaan tentang konkurensi data, “Apa yang terjadi jika lebih dari satu orang mengedit data yang sama pada waktu yang sama?”
Yang lebih beruntung di antara kita berurusan dengan aturan bisnis yang mengatakan "tidak masalah, yang terakhir menang."
Dalam kasus ini, konkurensi bukanlah masalah. Kemungkinan besar, ini tidak sesederhana itu, dan tidak ada solusi yang tepat untuk menyelesaikan setiap skenario sekaligus.
Secara default, Kerangka Kerja Entitas akan mengambil jalur "yang terakhir menang," yang berarti bahwa pembaruan terbaru diterapkan bahkan jika orang lain memperbarui data antara waktu data diambil dan waktu data disimpan.
Mari kita ambil contoh untuk memahaminya dengan lebih baik. Contoh berikut menambahkan kolom baru VersionNo di tabel Kursus.
Pergi ke desainer dan klik kanan pada jendela desainer dan pilih model pembaruan dari database…
Anda akan melihat bahwa kolom lain ditambahkan di Entitas Kursus.
Klik kanan pada kolom VersionNo yang baru dibuat dan pilih Properties dan ubah ConcurrencyMode menjadi Fixed seperti yang ditunjukkan pada gambar berikut.
Dengan ConcurrencyMode dari Course.VersionNo disetel ke Fixed, kapan pun sebuah Kursus diperbarui, perintah Perbarui akan mencari Kursus menggunakan EntityKey dan properti VersionNo-nya.
Mari kita lihat skenario sederhana. Dua pengguna mengambil kursus yang sama pada saat yang sama dan pengguna 1 mengubah judul kursus itu menjadi Matematika dan menyimpan perubahan sebelum pengguna 2. Nanti ketika pengguna 2 mengubah judul kursus itu yang diambil sebelum pengguna 1 menyimpan perubahannya, kasus pengguna 2 akan mendapatkan pengecualian konkurensi"User2: Optimistic Concurrency exception occured".
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
namespace DatabaseFirstDemo {
class Program {
static void Main(string[] args) {
Course c1 = null;
Course c2 = null;
//User 1 gets Course
using (var context = new UniContextEntities()) {
context.Configuration.ProxyCreationEnabled = false;
c1 = context.Courses.Where(s ⇒ s.CourseID == 1).Single();
}
//User 2 also get the same Course
using (var context = new UniContextEntities()) {
context.Configuration.ProxyCreationEnabled = false;
c2 = context.Courses.Where(s ⇒ s.CourseID == 1).Single();
}
//User 1 updates Course Title
c1.Title = "Edited from user1";
//User 2 updates Course Title
c2.Title = "Edited from user2";
//User 1 saves changes first
using (var context = new UniContextEntities()) {
try {
context.Entry(c1).State = EntityState.Modified;
context.SaveChanges();
} catch (DbUpdateConcurrencyException ex) {
Console.WriteLine("User1: Optimistic Concurrency exception occurred");
}
}
//User 2 saves changes after User 1.
//User 2 will get concurrency exection
//because CreateOrModifiedDate is different in the database
using (var context = new UniContextEntities()) {
try {
context.Entry(c2).State = EntityState.Modified;
context.SaveChanges();
} catch (DbUpdateConcurrencyException ex) {
Console.WriteLine("User2: Optimistic Concurrency exception occurred");
}
}
}
}
}