Zpracování výjimky souběžnosti v databázových aplikacích rozhraní .NET Framework
Poznámka:
Datové sady a související třídy jsou staršími technologiemi rozhraní .NET Framework z počátku 2000, které aplikacím umožňují pracovat s daty v paměti, zatímco aplikace jsou odpojené od databáze. Tyto technologie jsou zvláště užitečné pro aplikace, které uživatelům umožňují upravovat data a uchovávat změny zpět do databáze. I když se datové sady ukázaly jako velmi úspěšná technologie, doporučujeme, aby nové aplikace .NET používaly Entity Framework Core. Entity Framework poskytuje přirozenější způsob práce s tabulkovými daty jako objektovými modely a má jednodušší programovací rozhraní.
Výjimky souběžnosti (System.Data.DBConcurrencyException) jsou vyvolány, když se dva uživatelé pokusí změnit stejná data v databázi najednou. V tomto názorném postupu vytvoříte aplikaci pro Windows, která ukazuje, jak zachytit DBConcurrencyExceptionřádek, který způsobil chybu, a naučit se strategii, jak ji zpracovat.
Tento názorný postup vás provede následujícím procesem:
Vytvořte nový projekt aplikace model Windows Forms (.NET Framework).
Vytvořte novou datovou sadu založenou na tabulce Northwind Customers.
Vytvořte formulář s formulářem DataGridView pro zobrazení dat.
Vyplňte datovou sadu daty z tabulky Customers v databázi Northwind.
Pomocí funkce Zobrazit data tabulky v Průzkumníku serveru můžete získat přístup k datům tabulky Customers a změnit záznam.
Změňte stejný záznam na jinou hodnotu, aktualizujte datovou sadu a pokuste se zapsat změny do databáze, což má za následek vyvolání chyby souběžnosti.
Zachyťte chybu a pak zobrazte různé verze záznamu, což uživateli umožní určit, jestli má databáze pokračovat a aktualizovat, nebo ji zrušit.
Požadavky
Tento názorný postup používá SQL Server Express LocalDB a ukázkovou databázi Northwind.
Pokud nemáte SQL Server Express LocalDB, nainstalujte ho buď ze stránky pro stažení SQL Serveru Express, nebo prostřednictvím Instalační program pro Visual Studio. V Instalační program pro Visual Studio můžete sql Server Express LocalDB nainstalovat jako součást úlohy ukládání a zpracování dat nebo jako jednotlivé komponenty.
Následujícím postupem nainstalujte ukázkovou databázi Northwind:
V sadě Visual Studio otevřete okno Průzkumník objektů SQL Serveru. (SQL Server Průzkumník objektů se instaluje jako součást úlohy ukládání a zpracování dat v Instalační program pro Visual Studio.) Rozbalte uzel SQL Serveru. Klikněte pravým tlačítkem na instanci LocalDB a vyberte Nový dotaz.
Otevře se okno editoru dotazů.
Zkopírujte do schránky skript Northwind Transact-SQL. Tento skript T-SQL vytvoří zcela novou databázi Northwind a naplní ji daty.
Vložte skript T-SQL do editoru dotazů a pak zvolte tlačítko Spustit .
Po krátké době se dotaz dokončí a vytvoří se databáze Northwind.
Vytvoření nového projektu
Začněte vytvořením nové model Windows Forms aplikace:
V sadě Visual Studio v nabídce Soubor vyberte Nový>projekt.
V levém podokně rozbalte visual C# nebo Visual Basic a pak vyberte Plochu windows.
V prostředním podokně vyberte typ projektu aplikace model Windows Forms.
Pojmenujte projekt ConcurrencyWalkthrough a pak zvolte OK.
Projekt ConcurrencyWalkthrough se vytvoří a přidá do Průzkumník řešení a v návrháři se otevře nový formulář.
Vytvoření datové sady Northwind
Dále vytvořte datovou sadu s názvem NorthwindDataSet:
V nabídce Data zvolte Přidat nový zdroj dat.
Otevře se Průvodce konfigurací zdroje dat.
Na obrazovce Zvolit typ zdroje dat vyberte Databázi.
V seznamu dostupných připojení vyberte připojení k ukázkové databázi Northwind. Pokud připojení není v seznamu připojení k dispozici, vyberte Nové připojení.
Poznámka:
Pokud se připojujete k místnímu databázovému souboru, vyberte Po zobrazení dotazu Ne , pokud chcete soubor přidat do projektu.
Na obrazovce Uložit připojovací řetězec na obrazovce konfiguračního souboru aplikace vyberte Další.
Rozbalte uzel Tabulky a vyberte tabulku Zákazníci. Výchozí název datové sady by měl být NorthwindDataSet.
Výběrem možnosti Dokončit přidáte datovou sadu do projektu.
Vytvoření ovládacího prvku DataGridView vázaného na data
V této části vytvoříte System.Windows.Forms.DataGridView položku Zákazníci přetažením položky Zákazníci z okna Zdroje dat do formuláře Windows Form.
Pokud chcete otevřít okno Zdroje dat, v nabídce Data zvolte Zobrazit zdroje dat.
V okně Zdroje dat rozbalte uzel NorthwindDataSet a pak vyberte tabulku Zákazníci.
Vyberte šipku dolů na uzlu tabulky a pak v rozevíracím seznamu vyberte DataGridView .
Přetáhněte tabulku do prázdné oblasti formuláře.
Ovládací DataGridView prvek s názvem CustomersDataGridView a pojmenovaný BindingNavigator CustomersBindingNavigator se přidá do formuláře vázaného na BindingSource. To je zase vázané na tabulku Customers v NorthwindDataSet.
Vyzkoušení formuláře
Formulář teď můžete otestovat a ujistit se, že se chová podle očekávání až do tohoto okamžiku:
Výběrem klávesy F5 spusťte aplikaci.
Formulář se zobrazí s ovládacím DataGridView prvku, který je vyplněný daty z tabulky Zákazníci.
V nabídce Ladit vyberte Zastavit ladění.
Zpracování chyb souběžnosti
Způsob zpracování chyb závisí na konkrétních obchodních pravidlech, která řídí vaši aplikaci. V tomto názorném postupu používáme jako příklad následující strategii, jak zpracovat chybu souběžnosti.
Aplikace zobrazí uživatele se třemi verzemi záznamu:
Aktuální záznam v databázi
Původní záznam načtený do datové sady
Navrhované změny v datové sadě
Uživatel pak může buď přepsat databázi navrženou verzí, nebo zrušit aktualizaci a aktualizovat datovou sadu s novými hodnotami z databáze.
Povolení zpracování chyb souběžnosti
Vytvořte vlastní obslužnou rutinu chyby.
Umožňuje zobrazit možnosti pro uživatele.
Zpracujte odpověď uživatele.
Znovu odešlete aktualizaci nebo resetujte data v datové sadě.
Přidání kódu pro zpracování výjimky souběžnosti
Když se pokusíte provést aktualizaci a vyvolá se výjimka, obvykle chcete udělat něco s informacemi, které poskytuje vyvolaná výjimka. V této části přidáte kód, který se pokusí aktualizovat databázi. Zpracováváte také všechny DBConcurrencyException , které by mohly být vyvolány, a také jakékoli další výjimky.
Poznámka:
Metody CreateMessage
a ProcessDialogResults
metody jsou přidány později v návodu.
Pod metodu
Form1_Load
přidejte následující kód: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."); } }
Nahraďte metodu
CustomersBindingNavigatorSaveItem_Click
UpdateDatabase
voláním, aby vypadala takto:
Zobrazení možností pro uživatele
Kód, který jste právě napsali, volá proceduru CreateMessage
pro zobrazení informací o chybě uživateli. V tomto názorném postupu použijete okno se zprávou k zobrazení různých verzí záznamu pro uživatele. To umožňuje uživateli zvolit, jestli má záznam přepsat změnami nebo zrušit úpravy. Jakmile uživatel vybere možnost (klikne na tlačítko) v poli se zprávou, předá ProcessDialogResult
se do metody odpověď.
Vytvořte zprávu přidáním následujícího kódu do Editoru kódu. Pod metodu UpdateDatabase
zadejte tento kód:
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;
}
Zpracování odpovědi uživatele
K zpracování odpovědi uživatele do pole se zprávou potřebujete také kód. Tyto možnosti buď přepíší aktuální záznam v databázi navrhovanými změnami, nebo opustí místní změny a aktualizují tabulku dat záznamem, který je aktuálně v databázi. Pokud uživatel zvolí Ano, Merge volá se metoda s argumentem preserveChanges nastaveným na true. To způsobí, že pokus o aktualizaci bude úspěšný, protože původní verze záznamu teď odpovídá záznamu v databázi.
Pod kód, který byl přidán v předchozí části, přidejte následující kód:
// 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;
}
}
Testování chování formuláře
Formulář teď můžete otestovat a ujistit se, že se chová podle očekávání. Chcete-li simulovat porušení souběžnosti, změníte data v databázi po vyplnění NorthwindDataSet.
Výběrem klávesy F5 spusťte aplikaci.
Jakmile se formulář zobrazí, nechte ho spuštěný a přepněte do integrovaného vývojového prostředí sady Visual Studio.
V nabídce Zobrazení zvolte Průzkumník serveru.
V Průzkumníku serveru rozbalte připojení, které vaše aplikace používá, a poté rozbalte uzel Tabulky .
Klikněte pravým tlačítkem myši na tabulku Zákazníci a pak vyberte Zobrazit data tabulky.
V prvním záznamu (ALFKI) změňte ContactName na Maria Anders2.
Poznámka:
Přejděte na jiný řádek a potvrďte změnu.
Přepněte do spuštěného formuláře ConcurrencyWalkthrough.
V prvním záznamu ve formuláři (ALFKI) změňte ContactName na Maria Anders1.
Vyberte tlačítko Uložit.
Vyvolá se chyba souběžnosti a zobrazí se okno se zprávou.
Výběrem možnosti Ne se aktualizace zruší a aktualizuje se datová sada hodnotami, které jsou aktuálně v databázi. Když vyberete Ano , zapíše se navrhovaná hodnota do databáze.