Sdílet prostřednictvím


Návod: Zpracování výjimky souběžnosti

 

Publikováno: duben 2016

Výjimky souběžnosti (DBConcurrencyException) jsou vyvolány když dva uživatelé pokusí změnit stejná data v databázi ve stejnou dobu. V tomto návodu vytvoříte aplikaci systému Windows, který znázorňuje zachytávání DBConcurrencyException, vyhledáním řádek, který způsobil chybu a jedna strategie pro vás můžete použít pro zpracování ji.

Tento návod vás provede následující proces:

  1. Vytvořit nový aplikace Windows projektu.

  2. Vytvořit novou datovou sadu založenou na Northwind Customers tabulky.

  3. Vytvořit formulář s DataGridView zobrazíte data.

  4. Vyplnění datové sady s daty z Customers tabulky v databázi Northwind.

  5. Po vyplnění datové sady, použijte Nástroje Visual Database Tools v sadě Visual Studio k přímému přístupu Customers data tabulky a změna záznamu.

  6. Poté ve formuláři změnit stejný záznam na jinou hodnotu, aktualizovat datovou sadu a pokus o zápis změn do databáze, což vede k chybě souběžnost vyvolaných.

  7. Zachytit chybu a pak zobrazit různé verze na záznam, umožňující uživatelům určit, zda chcete pokračovat a aktualizaci databáze, nebo chcete-li zrušit aktualizaci.

Požadavky

Chcete-li dokončit tento návod, potřebujete:

Poznámka

Dialogová okna a příkazy nabídek, které se může lišit od těch popsaných v nápovědě v závislosti na aktivních nastaveních nebo edici. Chcete-li změnit nastavení, zvolte Nastavení importu a exportu na Nástroje nabídky. Další informace naleznete v tématu Přizpůsobení nastavení pro vývoj v sadě Visual Studio.

Vytvoření nového projektu

Vaše návod zahájíte vytvoření nové aplikace pro Windows.

Chcete-li vytvořit nový projekt aplikace pro systém Windows

  1. Z soubor nabídky, vytvořte nový projekt.

  2. Vyberte programovací jazyk v typy projektů podokně.

  3. Vyberte aplikace Windows v šablony podokně.

  4. Název projektu ConcurrencyWalkthrough, a potom klikněte na tlačítko OK.

    Visual Studio přidá projekt do Průzkumníku řešení a nový formulář zobrazí v návrháři.

Vytvoření datové sady Northwind

V této části vytvoříte datovou sadu s názvem NorthwindDataSet.

Chcete-li vytvořit NorthwindDataSet

  1. Z Data nabídce zvolte Přidat nový datový zdroj.

    Průvodce konfigurací zdroje dat Otevře.

  2. Vyberte databáze na Zvolte typ zdroje dat stránky.

  3. Vyberte připojení k ukázkové databázi Northwind ze seznamu dostupných připojení nebo klikněte na tlačítko nové připojení Pokud připojení není k dispozici v seznamu připojení.

    Poznámka

    Pokud se připojujete k místní databázový soubor, vyberte možnost č po dotazu, pokud byste chtěli přidat soubor do projektu.

  4. Klikněte na tlačítko Další na Uložit připojovací řetězec do konfiguračního souboru aplikace stránky.

  5. Rozbalte tabulky uzel a vyberte možnost Customers tabulky. Výchozí název pro datovou sadu by měl být NorthwindDataSet.

  6. Klikněte na tlačítko Dokončit přidání datové sady do projektu.

Vytvoření ovládacího prvku DataGridView vázaných na Data

V této části vytvoříte DataGridView přetažením Zákazníci položku z zdroje dat do formuláře systému Windows.

Vytvoření ovládacího prvku DataGridView, která je vázána k tabulce Zákazníci

  1. Z Data nabídce zvolte Zobrazit zdroje dat otevřete okno zdroje dat.

  2. Z zdroje dat rozbalte okno NorthwindDataSet uzel a vyberte možnost Zákazníci tabulky.

  3. Klikněte na šipku dolů na uzlu tabulky a vyberte DataGridView z rozevíracího seznamu.

  4. Přetáhněte tabulku na prázdnou oblast formuláře.

    A DataGridView ovládací prvek s názvem CustomersDataGridView a BindingNavigator s názvem CustomersBindingNavigator jsou přidány do formuláře, které jsou vázány na BindingSource která zase vázán Customers tabulky v NorthwindDataSet.

Kontrolní bod

Nyní můžete otestovat formuláře Ujistěte se, že se chová správně až do tohoto bodu.

Chcete-li otestovat formuláře

  1. Stisknutím klávesy F5 ke spuštění aplikace

    Formulář se zobrazí s DataGridView ovládacího prvku na něm, který je vyplněn data z Customers tabulky.

  2. Z ladění nabídce zvolte Zastavit ladění.

Zpracování chyb souběžnosti

Způsob zpracování chyb je závislá na konkrétní obchodní pravidla, kterými se řídí vaše aplikace. V tomto návodu po vygenerování narušení souběžného zpracování následující strategie ke zpracování chyby souběžnosti budou použity jako ilustraci:

Aplikace bude prezentovat tři verze záznam:

  • Aktuální záznam v databázi.

  • Původní záznam načtena do datové sady.

  • Navrhované změny v datové sadě.

Uživatel je pak možné přepsat databázi navrhované verzí nebo zrušit aktualizaci a aktualizovat datovou sadu s novými hodnotami z databáze.

Chcete-li povolit zpracování chyby souběžnosti

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

  2. Zobrazit možnosti pro uživatele.

  3. Zpracovat odpověď uživatele.

  4. Znovu odeslal aktualizaci nebo obnovení dat v datové sadě.

Přidání kódu pro zpracování výjimky souběžnosti

Když se pokusíte provést aktualizaci a získá vyvolána výjimka, obecně chcete udělat něco s informace poskytnuté vyvolanou výjimku.

V této části můžete přidat kód, který se pokusí o aktualizaci databáze a zpracovat žádné DBConcurrencyException může získat vyvolána, a také jiná výjimka.

Poznámka

CreateMessage a ProcessDialogResults metody bude přidán dále v tomto návodu.

Chcete-li přidat pro Chyba souběžného zpracování chyb
  1. Přidejte následující kód níže Form1_Load Metoda:

            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.");
                }
            }
    
        Private Sub UpdateDatabase()
    
            Try
                Me.CustomersTableAdapter.Update(Me.NorthwindDataSet.Customers)
                MsgBox("Update successful")
    
            Catch dbcx As Data.DBConcurrencyException
                Dim response As Windows.Forms.DialogResult
    
                response = MessageBox.Show(CreateMessage(CType(dbcx.Row, NorthwindDataSet.CustomersRow)),
                    "Concurrency Exception", MessageBoxButtons.YesNo)
    
                ProcessDialogResult(response)
    
            Catch ex As Exception
                MsgBox("An error was thrown while attempting to update the database.")
            End Try
        End Sub
    
  2. Nahradit CustomersBindingNavigatorSaveItem_Click metodu volání UpdateDatabase Metoda tak bude vypadat jako následující:

            private void customersBindingNavigatorSaveItem_Click(object sender, EventArgs e)
            {
                UpdateDatabase();
            }
    
        Private Sub CustomersBindingNavigatorSaveItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CustomersBindingNavigatorSaveItem.Click
            UpdateDatabase()
        End Sub
    

Možnosti zobrazení pro uživatele

Kód, který jste právě napsali volání CreateMessage postupem zobrazíte informace o chybě uživateli. V tomto návodu použije k zobrazení různých verzích záznamu uživateli a umožnit uživateli vybrat, zda chcete přepsat záznam změny nebo zrušit úpravy okno se zprávou. Jakmile uživatel vybere možnost (klikne na tlačítko) v okně se zprávou, je předáno odpověď ProcessDialogResult Metoda.

Chcete-li vytvořit zprávu, která se zobrazí uživateli
  • Vytvořit zprávu přidáním následujícího kódu Editor kódu. Zadejte níže tento kód UpdateDatabase Metoda.

            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;
            }
    
        Private Function CreateMessage(ByVal cr As NorthwindDataSet.CustomersRow) As String
            Return "Database: " & GetRowData(GetCurrentRowInDB(cr), 
                                             Data.DataRowVersion.Default) & vbCrLf &
                   "Original: " & GetRowData(cr, Data.DataRowVersion.Original) & vbCrLf &
                   "Proposed: " & GetRowData(cr, Data.DataRowVersion.Current) & vbCrLf &
                   "Do you still want to update the database with the proposed value?"
        End Function
    
    
        '--------------------------------------------------------------------------
        ' 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 TempCustomersDataTable As New NorthwindDataSet.CustomersDataTable
    
        Private Function GetCurrentRowInDB(
            ByVal RowWithError As NorthwindDataSet.CustomersRow
            ) As NorthwindDataSet.CustomersRow
    
            Me.CustomersTableAdapter.Fill(TempCustomersDataTable)
    
            Dim currentRowInDb As NorthwindDataSet.CustomersRow =
                TempCustomersDataTable.FindByCustomerID(RowWithError.CustomerID)
    
            Return currentRowInDb
        End Function
    
    
        '--------------------------------------------------------------------------
        ' This method takes a CustomersRow and RowVersion 
        ' and returns a string of column values to display to the user.
        '--------------------------------------------------------------------------
        Private Function GetRowData(ByVal custRow As NorthwindDataSet.CustomersRow,
            ByVal RowVersion As Data.DataRowVersion) As String
    
            Dim rowData As String = ""
    
            For i As Integer = 0 To custRow.ItemArray.Length - 1
                rowData &= custRow.Item(i, RowVersion).ToString() & " "
            Next
    
            Return rowData
        End Function
    

Zpracování odpověď uživatele

Budete také potřebovat kódu se zpracovat odpověď uživatele na okno zprávy. Možnosti jsou na aktuální záznam v databázi přepsat navrhované změny nebo opustit místní změny a aktualizujte tabulka dat s záznam aktuálně v databázi. Pokud uživatel vybere Ano, Merge Metoda je volána s preserveChanges argument nastaven na hodnotu true. To způsobí pokus o aktualizaci být úspěšná, protože původní verze záznamu nyní odpovídá záznam v databázi.

Ke zpracování uživatel vstup z okna se zprávou
  • Přidejte následující kód pod kód přidali v předchozím oddílu.

            // 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;
                }
            }
    
        ' 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 Sub ProcessDialogResult(ByVal response As Windows.Forms.DialogResult)
    
            Select Case response
    
                Case Windows.Forms.DialogResult.Yes
                    NorthwindDataSet.Customers.Merge(TempCustomersDataTable, True)
                    UpdateDatabase()
    
                Case Windows.Forms.DialogResult.No
                    NorthwindDataSet.Customers.Merge(TempCustomersDataTable)
                    MsgBox("Update cancelled")
            End Select
        End Sub
    

Testování

Nyní můžete otestovat formuláře Ujistěte se, že se chová podle očekávání. Pro simulaci narušení souběžného zpracování, budete muset změnit data v databázi po vyplnění NorthwindDataSet.

Chcete-li otestovat formuláře

  1. Stisknutím klávesy F5 ke spuštění aplikace.

  2. Jakmile se zobrazí formulář, ji nechat spuštěnou a přejděte do integrovaného vývojového prostředí sady Visual Studio.

  3. Z zobrazení nabídce zvolte Průzkumníku serveru.

  4. V Průzkumníku serveru, rozbalte připojení pomocí aplikace a potom rozbalte tabulky uzlu.

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

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

    Poznámka

    Přejděte na jiný řádek potvrzení změn.

  7. Přepnout ConcurrencyWalkthroughuživatele systémem formuláře.

  8. V prvním záznamu ve formuláři (ALFKI), změnit ContactName k Maria Anders1.

  9. Klikněte na tlačítko Uložit tlačítko.

    Je vyvolána chyba souběžnosti a zobrazí se okno se zprávou.

  10. Klepnutím na č zruší aktualizace a aktualizace datovou sadu s hodnotami v databázi, že kliknete na tlačítko Ano zapisuje navržená hodnota do databáze.

Viz také

Uložit data do databáze