Bagikan melalui


Menangani pengecualian konkurensi dalam aplikasi database .NET Framework

Catatan

Himpunan data dan kelas terkait adalah teknologi .NET Framework warisan dari awal 2000-an yang memungkinkan aplikasi untuk bekerja dengan data dalam memori saat aplikasi terputus dari database. Himpunan data tersebut sangat berguna untuk aplikasi yang mengaktifkan pengguna guna memodifikasi data dan mempertahankan perubahan kembali ke database. Meskipun himpunan data telah terbukti menjadi teknologi yang sangat sukses, sebaiknya aplikasi .NET baru menggunakan Entity Framework Core. Entity Framework menyediakan cara yang lebih alami untuk bekerja dengan data tabular sebagai model objek, dan memiliki antarmuka pemrograman yang lebih sederhana.

Pengecualian konkurensi (System.Data.DBConcurrencyException) dimunculkan ketika dua pengguna mencoba mengubah data yang sama dalam database secara bersamaan. Dalam panduan ini, Anda membuat aplikasi Windows yang menggambarkan cara menangkap DBConcurrencyException, menemukan baris yang menyebabkan kesalahan, dan mempelajari strategi tentang cara menanganinya.

Panduan ini membawa Anda melalui proses berikut:

  1. Buat proyek Formulir Windows App (.NET Framework) baru.

  2. Buat himpunan data baru berdasarkan tabel Pelanggan Northwind.

  3. Buat formulir dengan DataGridView untuk menampilkan data.

  4. Isi himpunan data dengan data dari tabel Pelanggan di database Northwind.

  5. Gunakan fitur Perlihatkan Data Tabel di Server Explorer untuk mengakses data tabel Pelanggan dan mengubah rekaman.

  6. Ubah rekaman yang sama ke nilai yang berbeda, perbarui himpunan data, dan coba tulis perubahan pada database, yang mengalihkan kesalahan konkurensi yang dimunculkan.

  7. Tangkap kesalahan, lalu tampilkan versi rekaman yang berbeda, memungkinkan pengguna untuk menentukan apakah akan melanjutkan dan memperbarui database, atau membatalkan pembaruan.

Prasyarat

Panduan ini menggunakan SQL Server Express LocalDB dan database sampel Northwind.

  1. Jika Anda tidak memiliki SQL Server Express LocalDB, pasang dari halaman unduhan SQL Server Express, atau melalui Alat Penginstal Visual Studio. Di Alat Penginstal Visual Studio, Anda dapat memasang SQL Server Express LocalDB sebagai bagian dari beban kerja Penyimpanan dan pemrosesan data, atau sebagai komponen individual.

  2. Instal database sampel Northwind dengan mengikuti langkah-langkah berikut:

    1. Di Visual Studio, buka jendela SQL Server Object Explorer. (SQL Server Object Explorer dipasang sebagai bagian dari beban kerja Penyimpanan dan pemrosesan data di Alat Penginstal Visual Studio.) Perluas node SQL Server. Klik kanan pada instans LocalDB Anda dan pilih Kueri Baru.

      Jendela editor kueri terbuka.

    2. Salin skrip Northwind Transact-SQL ke clipboard Anda. Skrip T-SQL ini membuat database Northwind dari awal dan mengisinya dengan data.

    3. Tempelkan skrip T-SQL ke editor kueri, lalu pilih tombol Jalankan.

      Setelah beberapa saat, kueri selesai berjalan dan database Northwind dibuat.

Membuat proyek baru

Mulailah dengan membuat aplikasi Formulir Windows baru:

  1. Di Visual Studio, di menu File, pilih Proyek>Baru.

  2. Perluas Visual C# atau Visual Basic di panel sebelah kiri, lalu pilih Windows Desktop.

  3. Di panel tengah, pilih jenis proyek Aplikasi Formulir Windows.

  4. Beri nama proyek ConcurrencyWalkthrough, lalu pilih OK.

    Proyek ConcurrencyWalkthrough dibuat dan ditambahkan ke Penjelajah Solusi, dan formulir baru terbuka di perancang.

Membuat himpunan data Northwind

Selanjutnya, buat himpunan data bernama NorthwindDataSet:

  1. Pada menu Data , pilih Tambahkan Sumber Data Baru.

    Wizard Konfigurasi Sumber Data terbuka.

  2. Pada layar Pilih Tipe Sumber Data, pilih Database.

    Panduan Konfigurasi Sumber Data di Visual Studio

  3. Pilih koneksi ke database sampel Northwind dari daftar koneksi yang tersedia. Jika koneksi tidak tersedia dalam daftar koneksi, pilih Koneksi ion baru.

    Catatan

    Jika Anda menyambungkan ke file database lokal, pilih Tidak saat ditanya apakah Anda ingin menambahkan file ke proyek Anda.

  4. Pada layar Simpan string koneksi ke file konfigurasi aplikasi, pilih Berikutnya.

  5. Perluas simpul Tabel dan pilih tabel Pelanggan. Nama default untuk himpunan data harus NorthwindDataSet.

  6. Pilih Selesai untuk menambahkan himpunan data ke proyek.

Membuat kontrol DataGridView terikat data

Di bagian ini, Anda membuat System.Windows.Forms.DataGridView dengan menyeret item Pelanggan dari jendela Sumber Data ke Formulir Windows Anda.

  1. Untuk membuka jendela Sumber Data, pada menu Data , pilih Perlihatkan Sumber Data.

  2. Di jendela Sumber Data, perluas simpul NorthwindDataSet , lalu pilih tabel Pelanggan .

  3. Pilih panah bawah pada simpul tabel, lalu pilih DataGridView di daftar dropdown.

  4. Seret tabel ke area kosong formulir Anda.

    Kontrol bernama CustomersDataGridView, dan BindingNavigator customersBindingNavigator bernama, ditambahkan ke formulir yang terikat ke BindingSource.DataGridView Ini, pada gilirannya, terikat ke tabel Pelanggan di NorthwindDataSet.

Menguji formulir

Anda sekarang dapat menguji formulir untuk memastikannya bertingkah seperti yang diharapkan hingga saat ini:

  1. Pilih F5 untuk menjalankan aplikasi.

    Formulir muncul dengan DataGridView kontrol di atasnya yang diisi dengan data dari tabel Pelanggan.

  2. Pada menu Debug, pilih Hentikan Debugging.

Menangani kesalahan konkurensi

Cara Anda menangani kesalahan tergantung pada aturan bisnis tertentu yang mengatur aplikasi Anda. Untuk panduan ini, kami menggunakan strategi berikut sebagai contoh cara menangani kesalahan konkurensi.

Aplikasi ini menyajikan pengguna dengan tiga versi rekaman:

  • Rekaman saat ini dalam database

  • Rekaman asli yang dimuat ke dalam himpunan data

  • Perubahan yang diusulkan dalam himpunan data

Pengguna kemudian dapat menimpa database dengan versi yang diusulkan, atau membatalkan pembaruan dan me-refresh himpunan data dengan nilai baru dari database.

Untuk mengaktifkan penanganan kesalahan konkurensi

  1. Buat handler kesalahan kustom.

  2. Tampilkan pilihan kepada pengguna.

  3. Memproses respons pengguna.

  4. Mengirim ulang pembaruan, atau mengatur ulang data dalam himpunan data.

Menambahkan kode untuk menangani pengecualian konkurensi

Saat Anda mencoba melakukan pembaruan dan pengecualian dimunculkan, Anda umumnya ingin melakukan sesuatu dengan informasi yang disediakan oleh pengecualian yang dinaikkan. Di bagian ini, Anda menambahkan kode yang mencoba memperbarui database. Anda juga menangani apa pun DBConcurrencyException yang mungkin dimunculkan, serta pengecualian lainnya.

Catatan

Metode CreateMessage dan ProcessDialogResults ditambahkan nanti di panduan.

  1. Tambahkan kode berikut di bawah Form1_Load metode :

    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.");
        }
    }
    

  1. CustomersBindingNavigatorSaveItem_Click Ganti metode untuk memanggil UpdateDatabase metode sehingga terlihat seperti berikut ini:

    private void customersBindingNavigatorSaveItem_Click(object sender, EventArgs e)
    {
        UpdateDatabase();
    }
    

Menampilkan pilihan kepada pengguna

Kode yang baru saja Anda tulis memanggil CreateMessage prosedur untuk menampilkan informasi kesalahan kepada pengguna. Untuk panduan ini, Anda menggunakan kotak pesan untuk menampilkan versi rekaman yang berbeda kepada pengguna. Ini memungkinkan pengguna untuk memilih apakah akan menimpa rekaman dengan perubahan atau membatalkan pengeditan. Setelah pengguna memilih opsi (mengklik tombol) pada kotak pesan, respons diteruskan ke ProcessDialogResult metode .

Buat pesan dengan menambahkan kode berikut ke Editor Kode. Masukkan kode ini di UpdateDatabase bawah metode :

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;
}

Memproses respons pengguna

Anda juga memerlukan kode untuk memproses respons pengguna terhadap kotak pesan. Opsinya adalah menimpa rekaman saat ini dalam database dengan perubahan yang diusulkan, atau meninggalkan perubahan lokal dan me-refresh tabel data dengan rekaman yang saat ini ada di database. Jika pengguna memilih Ya, metode dipanggil dengan argumen preserveChanges diatur ke true.Merge Ini menyebabkan upaya pembaruan berhasil, karena versi asli rekaman sekarang cocok dengan rekaman dalam database.

Tambahkan kode berikut di bawah kode yang ditambahkan di bagian sebelumnya:

// 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;
    }
}

Menguji perilaku formulir

Anda sekarang dapat menguji formulir untuk memastikan formulir tersebut berulah seperti yang diharapkan. Untuk mensimulasikan pelanggaran konkurensi, Anda mengubah data dalam database setelah mengisi NorthwindDataSet.

  1. Pilih F5 untuk menjalankan aplikasi.

  2. Setelah formulir muncul, biarkan berjalan dan beralih ke Visual Studio IDE.

  3. Pada menu Tampilan, pilih Penjelajah Server.

  4. Di Server Explorer, perluas koneksi yang digunakan aplikasi Anda, lalu perluas simpul Tabel .

  5. Klik kanan tabel Pelanggan, lalu pilih Perlihatkan Data Tabel.

  6. Di rekaman pertama (ALFKI), ubah ContactName menjadi Maria Anders2.

    Catatan

    Navigasikan ke baris lain untuk menerapkan perubahan.

  7. Beralih ke formulir berjalan ConcurrencyWalkthrough.

  8. Dalam rekaman pertama pada formulir (ALFKI), ubah ContactName menjadi Maria Anders1.

  9. Pilih tombol Simpan.

    Kesalahan konkurensi muncul, dan kotak pesan muncul.

    Memilih Tidak membatalkan pembaruan dan memperbarui himpunan data dengan nilai yang saat ini ada di database. Memilih Ya menulis nilai yang diusulkan ke database.