.NET Framework veritabanı uygulamalarında eşzamanlılık özel durumunu işleme
Not
Veri kümeleri ve ilgili sınıflar, uygulamaların veritabanıyla bağlantısı kesilirken uygulamaların bellekteki verilerle çalışmasını sağlayan 2000'lerin başlarındaki eski .NET Framework teknolojileridir. Teknolojiler özellikle kullanıcıların verileri değiştirmesine ve değişiklikleri veritabanında kalıcı hale getirebilmesine olanak tanıyan uygulamalar için kullanışlıdır. Veri kümelerinin çok başarılı bir teknoloji olduğu kanıtlanmış olsa da, yeni .NET uygulamalarının Entity Framework Core kullanmasını öneririz. Entity Framework, tablosal verilerle nesne modelleri olarak çalışmak için daha doğal bir yol sağlar ve daha basit bir programlama arabirimine sahiptir.
Eşzamanlılık özel durumları (System.Data.DBConcurrencyException), iki kullanıcı aynı anda bir veritabanında aynı verileri değiştirmeye çalıştığında ortaya çıkar. Bu kılavuzda, hataya neden olan satırın nasıl yakalanacağını gösteren bir DBConcurrencyExceptionWindows uygulaması oluşturacak ve nasıl işleneceğini öğreneceksiniz.
Bu izlenecek yol aşağıdaki işlemde size yol göstermektedir:
Yeni bir Windows Forms Uygulaması (.NET Framework) projesi oluşturun.
Northwind Müşterileri tablosunu temel alan yeni bir veri kümesi oluşturun.
Verileri görüntülemek için ile bir DataGridView form oluşturun.
Veri kümesini Northwind veritabanındaki Müşteriler tablosundaki verilerle doldurun.
Sunucu Gezgini'nde Tablo Verilerini Göster özelliğini kullanarak Customers-table verilerine erişin ve bir kaydı değiştirin.
Aynı kaydı farklı bir değerle değiştirin, veri kümesini güncelleştirin ve değişiklikleri veritabanına yazmaya çalıştığınızda eşzamanlılık hatası oluşur.
Hatayı yakalayın, ardından kaydın farklı sürümlerini görüntüleyerek kullanıcının devam edip veritabanını güncelleştirmesini veya güncelleştirmeyi iptal edip etmeyeceğini belirlemesine olanak tanır.
Önkoşullar
Bu kılavuzda SQL Server Express LocalDB ve Northwind örnek veritabanı kullanılmaktadır.
SQL Server Express LocalDB'niz yoksa, SQL Server Express indirme sayfasından veya Visual Studio Yükleyicisi aracılığıyla yükleyin. Visual Studio Yükleyicisi, SQL Server Express LocalDB'yi Veri depolama ve işleme iş yükünün bir parçası olarak veya tek bir bileşen olarak yükleyebilirsiniz.
Aşağıdaki adımları izleyerek Northwind örnek veritabanını yükleyin:
Visual Studio'da SQL Server Nesne Gezgini penceresini açın. (SQL Server Nesne Gezgini, Visual Studio Yükleyicisi Veri depolama ve işleme iş yükünün bir parçası olarak yüklenir.) SQL Server düğümünü genişletin. LocalDB örneğinize sağ tıklayın ve Yeni Sorgu'yu seçin.
Sorgu düzenleyicisi penceresi açılır.
Northwind Transact-SQL betiğini panonuza kopyalayın. Bu T-SQL betiği, Northwind veritabanını sıfırdan oluşturur ve verilerle doldurur.
T-SQL betiğini sorgu düzenleyicisine yapıştırın ve ardından Yürüt düğmesini seçin.
Kısa bir süre sonra sorgunun çalışması tamamlanır ve Northwind veritabanı oluşturulur.
Yeni proje oluşturma
Yeni bir Windows Forms uygulaması oluşturarak başlayın:
Visual Studio'da, Dosya menüsünde Yeni Proje'yi> seçin.
Sol bölmede Visual C# veya Visual Basic'i genişletin, ardından Windows Masaüstü'nü seçin.
Orta bölmede Windows Forms Uygulaması proje türünü seçin.
Projeye ConcurrencyWalkthrough adını verin ve Tamam'ı seçin.
ConcurrencyWalkthrough projesi oluşturulur ve Çözüm Gezgini eklenir ve tasarımcıda yeni bir form açılır.
Northwind veri kümesini oluşturma
Ardından NorthwindDataSet adlı bir veri kümesi oluşturun:
Veri menüsünde Yeni Veri kaynağı ekle'yi seçin.
Veri Kaynağı Yapılandırma Sihirbazı açılır.
Veri Kaynağı Türü Seçin ekranında Veritabanı'nı seçin.
Kullanılabilir bağlantılar listesinden Northwind örnek veritabanına bir bağlantı seçin. Bağlantı, bağlantı listesinde kullanılamıyorsa Yeni Bağlantı'yı seçin.
Not
Yerel bir veritabanı dosyasına bağlanıyorsanız, dosyayı projenize eklemek isteyip istediğiniz sorulduğunda Hayır'ı seçin.
bağlantı dizesi uygulama yapılandırma dosyasına kaydet ekranında İleri'yi seçin.
Tablolar düğümünü genişletin ve Müşteriler tablosunu seçin. Veri kümesinin varsayılan adı NorthwindDataSet olmalıdır.
Veri kümesini projeye eklemek için Son'u seçin.
Veriye bağlı DataGridView denetimi oluşturma
Bu bölümde, Veri Kaynakları penceresindeki Müşteriler öğesini Windows Formunuza sürükleyerek bir System.Windows.Forms.DataGridView oluşturacaksınız.
Veri Kaynakları penceresini açmak için, Veri menüsünde Veri Kaynaklarını Göster'i seçin.
Veri Kaynakları penceresinde NorthwindDataSet düğümünü genişletin ve müşteriler tablosunu seçin.
Tablo düğümündeki aşağı oku seçin ve ardından açılan listeden DataGridView'ı seçin.
Tabloyu formunuzun boş bir alanına sürükleyin.
CustomersDataGridView adlı bir denetim ve CustomersBindingNavigator adlı denetimBindingNavigator, ile ilişkili BindingSourceforma DataGridView eklenir. Bu da NorthwindDataSet'teki Customers tablosuna bağlıdır.
Formu test etme
Artık formu test ederek bu noktaya kadar beklendiği gibi davrandığından emin olabilirsiniz:
Uygulamayı çalıştırmak için F5'i seçin.
Form, Üzerinde Müşteriler tablosundaki verilerle doldurulmuş bir DataGridView denetimle birlikte görünür.
Hata Ayıklama menüsünde Hata Ayıklamayı Durdur’u seçin.
Eşzamanlılık hatalarını işleme
Hataların nasıl işleneceğiniz, uygulamanızı yöneten belirli iş kurallarına bağlıdır. Bu kılavuzda eşzamanlılık hatasının nasıl işleneceğini gösteren bir örnek olarak aşağıdaki stratejiyi kullanırız.
Uygulama kullanıcıya kaydın üç sürümünü sunar:
Veritabanındaki geçerli kayıt
Veri kümesine yüklenen özgün kayıt
Veri kümesinde önerilen değişiklikler
Kullanıcı daha sonra önerilen sürümle veritabanının üzerine yazabilecek veya güncelleştirmeyi iptal edip veri kümesini veritabanındaki yeni değerlerle yenileyebilir.
Eşzamanlılık hatalarının işlenmesini etkinleştirmek için
Özel bir hata işleyicisi oluşturun.
Kullanıcıya seçimleri görüntüleme.
Kullanıcının yanıtını işleme.
Güncelleştirmeyi yeniden gönderin veya veri kümesindeki verileri sıfırlayın.
Eşzamanlılık özel durumunu işlemek için kod ekleme
Bir güncelleştirme gerçekleştirmeye çalıştığınızda ve özel durum oluştuğunda, genellikle yükseltilmiş özel durum tarafından sağlanan bilgilerle bir şeyler yapmak istersiniz. Bu bölümde veritabanını güncelleştirmeye çalışan kodu ekleyebilirsiniz. Ayrıca, oluşturulabilecek tüm DBConcurrencyException özel durumları ve diğer özel durumları da işlersiniz.
Not
CreateMessage
ve ProcessDialogResults
yöntemleri, izlenecek yolda daha sonra eklenir.
Yönteminin altına
Form1_Load
aşağıdaki kodu ekleyin:private void UpdateDatabase() { try { this.customersTableAdapter.Update(this.northwindDataSet.Customers); MessageBox.Show("Update successful"); } catch (DBConcurrencyException dbcx) { DialogResult response = MessageBox.Show(CreateMessage((NorthwindDataSet.CustomersRow) (dbcx.Row)), "Concurrency Exception", MessageBoxButtons.YesNo); ProcessDialogResult(response); } catch (Exception ex) { MessageBox.Show("An error was thrown while attempting to update the database."); } }
CustomersBindingNavigatorSaveItem_Click
yöntemini aşağıdaki gibi görünecek şekilde çağıracakUpdateDatabase
şekilde değiştirin:
Kullanıcıya seçimleri görüntüleme
Az önce yazdığınız kod, kullanıcıya hata bilgilerini görüntülemek için yordamı çağırır CreateMessage
. Bu kılavuzda, kaydın farklı sürümlerini kullanıcıya görüntülemek için bir ileti kutusu kullanırsınız. Bu, kullanıcının değişikliklerle kaydın üzerine yazılmasını mı yoksa düzenlemeyi iptal etmeyi mi seçeceğini seçmesini sağlar. Kullanıcı ileti kutusunda bir seçeneği (bir düğmeye tıklar) seçtikten sonra, yanıt yöntemine ProcessDialogResult
geçirilir.
Kod Düzenleyicisi'ne aşağıdaki kodu ekleyerek iletiyi oluşturun. Yönteminin UpdateDatabase
altına şu kodu girin:
private string CreateMessage(NorthwindDataSet.CustomersRow cr)
{
return
"Database: " + GetRowData(GetCurrentRowInDB(cr), DataRowVersion.Default) + "\n" +
"Original: " + GetRowData(cr, DataRowVersion.Original) + "\n" +
"Proposed: " + GetRowData(cr, DataRowVersion.Current) + "\n" +
"Do you still want to update the database with the proposed value?";
}
//--------------------------------------------------------------------------
// This method loads a temporary table with current records from the database
// and returns the current values from the row that caused the exception.
//--------------------------------------------------------------------------
private NorthwindDataSet.CustomersDataTable tempCustomersDataTable =
new NorthwindDataSet.CustomersDataTable();
private NorthwindDataSet.CustomersRow GetCurrentRowInDB(NorthwindDataSet.CustomersRow RowWithError)
{
this.customersTableAdapter.Fill(tempCustomersDataTable);
NorthwindDataSet.CustomersRow currentRowInDb =
tempCustomersDataTable.FindByCustomerID(RowWithError.CustomerID);
return currentRowInDb;
}
//--------------------------------------------------------------------------
// This method takes a CustomersRow and RowVersion
// and returns a string of column values to display to the user.
//--------------------------------------------------------------------------
private string GetRowData(NorthwindDataSet.CustomersRow custRow, DataRowVersion RowVersion)
{
string rowData = "";
for (int i = 0; i < custRow.ItemArray.Length ; i++ )
{
rowData = rowData + custRow[i, RowVersion].ToString() + " ";
}
return rowData;
}
Kullanıcının yanıtını işleme
Ayrıca kullanıcının ileti kutusuna verdiği yanıtı işlemek için koda da ihtiyacınız vardır. Seçenekler, önerilen değişiklikle veritabanındaki geçerli kaydın üzerine yazmak veya yerel değişiklikleri bırakıp veri tablosunu veritabanındaki kayıtla yenilemektir. Kullanıcı Evet'i seçerse, preserveChanges bağımsız değişkeni true olarak ayarlanmış şekilde yöntemi çağrılır.Merge Bu, kaydın özgün sürümü artık veritabanındaki kayıtla eşleştiğinden güncelleştirme girişiminin başarılı olması için neden olur.
Önceki bölümde eklenen kodun altına aşağıdaki kodu ekleyin:
// This method takes the DialogResult selected by the user and updates the database
// with the new values or cancels the update and resets the Customers table
// (in the dataset) with the values currently in the database.
private void ProcessDialogResult(DialogResult response)
{
switch (response)
{
case DialogResult.Yes:
northwindDataSet.Merge(tempCustomersDataTable, true, MissingSchemaAction.Ignore);
UpdateDatabase();
break;
case DialogResult.No:
northwindDataSet.Merge(tempCustomersDataTable);
MessageBox.Show("Update cancelled");
break;
}
}
Form davranışını test edin
Artık formu test edebilir ve beklendiği gibi davrandığından emin olabilirsiniz. Eşzamanlılık ihlali simülasyonu yapmak için NorthwindDataSet'i doldurduktan sonra veritabanındaki verileri değiştirirsiniz.
Uygulamayı çalıştırmak için F5'i seçin.
Form göründükten sonra çalışır durumda bırakın ve Visual Studio IDE'ye geçin.
Görünüm menüsünde Sunucu Gezgini'ni seçin.
Sunucu Gezgini'nde, uygulamanızın kullandığı bağlantıyı genişletin ve ardından Tablolar düğümünü genişletin.
Müşteriler tablosuna sağ tıklayın ve tablo verilerini göster'i seçin.
İlk kayıtta (ALFKI), ContactName değerini Maria Anders2 olarak değiştirin.
Not
Değişikliği işlemek için farklı bir satıra gidin.
ConcurrencyWalkthrough'un çalışan formuna geçin.
Formdaki (ALFKI) ilk kayıtta ContactName değerini Maria Anders1 olarak değiştirin.
Kaydet düğmesini seçin.
Eşzamanlılık hatası oluşturulur ve ileti kutusu görüntülenir.
Hayır'ın seçilmesi güncelleştirmeyi iptal eder ve veri kümesini şu anda veritabanında bulunan değerlerle güncelleştirir. Evet seçildiğinde önerilen değer veritabanına yazılır.