Zpracování výjimky souběžnosti

Platí pro:yesnokód Visual Studio Visual Studio pro Mac noVisual Studio

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 Windows aplikaci, která ukazuje, jak zachytit DBConcurrencyExceptionřádek, najít řádek, který chybu způsobil, a naučit se strategii, jak ji zpracovat.

Tento názorný postup vás provede následujícím postupem:

  1. Vytvořte nový projekt aplikace model Windows Forms.

  2. Vytvořte novou datovou sadu založenou na tabulce Northwind Customers.

  3. Vytvořte formulář s DataGridView datem, který zobrazí data.

  4. Vyplňte datovou sadu daty z tabulky Customers v databázi Northwind.

  5. Pomocí funkce Zobrazit data tabulky v Průzkumníku serveru můžete získat přístup k datům tabulky Customers-table a změnit záznam.

  6. Změňte stejný záznam na jinou hodnotu, aktualizujte datovou sadu a pokuste se zapsat změny do databáze, což vede k chybě souběžnosti.

  7. Zachyťte chybu a pak zobrazte různé verze záznamu, což uživateli umožňuje určit, jestli chcete pokračovat a aktualizovat databázi, nebo aktualizaci zrušit.

Požadavky

Tento návod používá SQL Server Express LocalDB a ukázkovou databázi Northwind.

  1. Pokud nemáte SQL Server Express LocalDB, nainstalujte ji buď ze stránky pro stažení SQL Server Express, nebo prostřednictvím Instalační program pro Visual Studio. V Instalační program pro Visual Studio můžete nainstalovat SQL Server Express LocalDB jako součást úlohy ukládání a zpracování dat nebo jako jednotlivá komponenta.

  2. Následujícím postupem nainstalujte ukázkovou databázi Northwind:

    1. V Visual Studio otevřete okno SQL Server Průzkumník objektů. (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 Server. Klikněte pravým tlačítkem na instanci LocalDB a vyberte Nový dotaz.

      Otevře se okno editoru dotazů.

    2. Zkopírujte skript Northwind Transact-SQL do schránky. Tento skript T-SQL vytvoří zcela novou databázi Northwind a naplní ji daty.

    3. 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é aplikace model Windows Forms:

  1. V Visual Studio vyberte v nabídce Soubor možnost Nový>Project.

  2. Rozbalte visual C# nebo Visual Basic v levém podokně a pak vyberte Windows Plocha.

  3. V prostředním podokně vyberte typ projektu aplikace model Windows Forms.

  4. 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:

  1. V nabídce Data zvolte Přidat nový zdroj dat.

    Otevře se Průvodce konfigurací zdroje dat.

  2. Na obrazovce Zvolit typ zdroje dat vyberte Databázi.

    Data Source Configuration Wizard in Visual Studio

  3. Ze seznamu dostupných připojení vyberte připojení k ukázkové databázi Northwind. Pokud připojení není v seznamu připojení dostupné, vyberte Nové připojení.

    Poznámka

    Pokud se připojujete k místnímu databázovému souboru, vyberte možnost Ne , pokud se zobrazí dotaz, jestli chcete soubor přidat do projektu.

  4. V okně Uložit připojovací řetězec na blokování konfiguračního souboru aplikace vyberte Další.

  5. Rozbalte uzel Tabulky a vyberte tabulku Zákazníci . Výchozí název datové sady by měl být NorthwindDataSet.

  6. 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.

  1. Pokud chcete otevřít okno Zdroje dat , v nabídce Data zvolte Zobrazit zdroje dat.

  2. V okně Zdroje dat rozbalte uzel NorthwindDataSet a pak vyberte tabulku Zákazníci .

  3. Vyberte šipku dolů na uzlu tabulky a pak v rozevíracím seznamu vyberte DataGridView .

  4. Přetáhněte tabulku do prázdné oblasti formuláře.

    Ovládací DataGridView prvek s názvem CustomersDataGridView a pojmenovaný BindingNavigatorCustomersBindingNavigator se přidá do formuláře vázaného BindingSourcena . To je zase vázané na tabulku Customers v NorthwindDataSet.

Otestování formuláře

Formulář teď můžete otestovat a ujistit se, že se chová podle očekávání až do tohoto bodu:

  1. 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.

  2. 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žijeme následující strategii jako příklad, 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 databázi buď přepsat navrženou verzí, nebo zrušit aktualizaci a aktualizovat datovou sadu s novými hodnotami z databáze.

Povolení zpracování chyb souběžnosti

  1. Vytvořte vlastní obslužnou rutinu chyby.

  2. Zobrazí možnosti pro uživatele.

  3. Zpracujte odpověď uživatele.

  4. 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, stejně jako jakékoli jiné výjimky.

Poznámka

Metody CreateMessage a ProcessDialogResults metody se přidají později v návodu.

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

  1. Nahraďte metodu CustomersBindingNavigatorSaveItem_ClickUpdateDatabase voláním metody tak, aby vypadala takto:

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

Zobrazení voleb uživateli

Kód, který jste právě napsali, volá proceduru CreateMessage k zobrazení informací o chybě uživateli. Pro účely tohoto návodu použijete pole se zprávou k zobrazení různých verzí záznamu uživateli. Tím umožníte uživateli zvolit, jestli chcete záznam přepsat změnami nebo zrušit úpravu. Jakmile uživatel vybere možnost (klikne na tlačítko) v poli se zprávou, předá se odpověď metodě ProcessDialogResult .

Vytvořte zprávu přidáním následujícího kódu do Editoru kódu. Zadejte tento kód pod metodu UpdateDatabase :

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

Potřebujete také kód ke zpracování odpovědi uživatele do pole zprávy. Mezi možnosti patří přepsání aktuálního záznamu v databázi pomocí navrhované změny, nebo opuštění místních změn a aktualizace tabulky 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 hodnotu true. Tím dojde k úspěšnému pokusu o aktualizaci, protože původní verze záznamu teď odpovídá záznamu v databázi.

Pod kód přidaný 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.

  1. Výběrem klávesy F5 aplikaci spusťte.

  2. Jakmile se formulář zobrazí, ponechte ho spuštěný a přepněte na integrované vývojové prostředí (IDE) Visual Studio.

  3. V nabídce Zobrazení zvolte Průzkumník serveru.

  4. V Průzkumníku serveru rozbalte připojení, které aplikace používá, a pak rozbalte uzel Tabulky .

  5. Klikněte pravým tlačítkem myši na tabulku Zákazníci a pak vyberte Zobrazit data tabulky.

  6. V prvním záznamu (ALFKI) změňte ContactName na Maria Anders2.

    Poznámka

    Pokud chcete změnu potvrdit, přejděte na jiný řádek.

  7. Přepněte do spuštěného formuláře ConcurrencyWalkthrough.

  8. V prvním záznamu ve formuláři (ALFKI) změňte ContactName na Maria Anders1.

  9. 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 datovou sadu hodnotami, které jsou aktuálně v databázi. Výběrem možnosti Ano zapíšete navrženou hodnotu do databáze.

Viz také