Implementace optimistického řízení souběžnosti ovládacím prvkem SqlDataSource (VB)

Scott Mitchell

Stáhnout PDF

V tomto kurzu si projdeme základy optimistického řízení souběžnosti a pak prozkoumáme, jak ho implementovat pomocí ovládacího prvku SqlDataSource.

Úvod

V předchozím kurzu jsme prozkoumali, jak do ovládacího prvku SqlDataSource přidat možnosti vkládání, aktualizace a odstraňování. Stručně řečeno, abychom mohli tyto funkce poskytnout, potřebovali jsme zadat odpovídající INSERTpříkazy , UPDATEnebo DELETE SQL ve vlastnostech ovládacích prvků UpdateCommandInsertCommand, nebo DeleteCommand spolu s příslušnými parametry v InsertParameterskolekcích , UpdateParametersa DeleteParameters . I když tyto vlastnosti a kolekce lze zadat ručně, tlačítko Průvodce konfigurací zdroje dat s tlačítkem Upřesnit nabízí zaškrtávací políčko Generovat INSERTpříkazy , UPDATEa DELETE , které automaticky vytvoří tyto příkazy na SELECT základě příkazu .

Kromě zaškrtávacího políčka Generovat INSERTpříkazy , UPDATEa DELETE obsahuje dialogové okno Rozšířené možnosti generování SQL možnost Použít optimistickou souběžnost (viz Obrázek 1). Pokud je tato možnost zaškrtnutá WHERE , klauzule v automaticky vygenerovaných UPDATE příkazech a DELETE se upraví tak, aby provedly aktualizaci nebo odstranění pouze v případě, že se podkladová data databáze od posledního načtení dat uživatelem do mřížky nezměnila.

Podporu optimistické souběžnosti můžete přidat v dialogovém okně Upřesnit možnosti generování SQL.

Obrázek 1: Podporu optimistické souběžnosti můžete přidat v dialogovém okně Rozšířené možnosti generování SQL.

V kurzu Implementace optimistické souběžnosti jsme prozkoumali základy řízení optimistické souběžnosti a jeho přidání do objektu ObjectDataSource. V tomto kurzu se podíváme na základy optimistického řízení souběžnosti a pak prozkoumáme, jak ho implementovat pomocí sqldatasource.

Rekapitulace optimistické souběžnosti

U webových aplikací, které umožňují více souběžným uživatelům upravovat nebo odstraňovat stejná data, existuje možnost, že jeden uživatel nechtěně přepíše jiného uživatele. V kurzu Implementace optimistické souběžnosti jsem uvedl následující příklad:

Představte si, že dva uživatelé, Jisun a Sam, navštívili stránku v aplikaci, která návštěvníkům umožňovala aktualizovat a odstraňovat produkty prostřednictvím ovládacího prvku GridView. Oba kliknou na tlačítko Upravit pro Chai přibližně ve stejnou dobu. Jisun změní název produktu na Chai Tea a klikne na tlačítko Aktualizovat. Čistý výsledek je příkaz UPDATE , který se odešle do databáze, který nastaví všechna aktualizovatelná pole produktu (i když Jisun aktualizoval pouze jedno pole , ProductName). V tomto okamžiku má databáze pro tento konkrétní produkt hodnoty Chai Čaj, kategorii Nápoje, dodavatele Exotic Liquids atd. Na obrazovce GridView na sam s však stále zobrazuje název produktu v upravitelném řádku GridView jako Chai. Několik sekund po potvrzení změn jisun sam aktualizuje kategorii na Condiments a klikne na Aktualizovat. Výsledkem je UPDATE příkaz odeslaný do databáze, který nastaví název produktu na Chai, CategoryID na odpovídající ID kategorie Condiments atd. Změny jisunu v názvu produktu byly přepsány.

Tuto interakci znázorňuje obrázek 2.

Když dva uživatelé současně aktualizují záznam, existuje možnost, že jeden uživatel může změnit jiné uživatele.

Obrázek 2: Když dva uživatelé současně aktualizují záznam, existuje potenciál pro jednoho uživatele změny k přepsání ostatních (kliknutím zobrazíte obrázek v plné velikosti)

Aby se zabránilo tomuto scénáři, musí být implementována forma řízení souběžnosti . Optimistická souběžnost , na kterou se tento kurz zaměřuje, vychází z předpokladu, že i když občas může docházet ke konfliktům souběžnosti, v drtivé většině případů k takovým konfliktům nedojde. Proto pokud dojde ke konfliktu, optimistické řízení souběžnosti jednoduše informuje uživatele, že jeho změny nelze uložit, protože jiný uživatel upravil stejná data.

Poznámka

U aplikací, u kterých se předpokládá, že dojde k mnoha konfliktům souběžnosti, nebo pokud takové konflikty nejsou přípustné, je možné místo toho použít pesimistické řízení souběžnosti. Podrobnější diskuzi o pesimistickém řízení souběžnosti najdete v kurzu Implementace optimistické souběžnosti.

Řízení optimistické souběžnosti funguje tak, že zajišťuje, aby aktualizovaný nebo odstraněný záznam měl stejné hodnoty jako při spuštění procesu aktualizace nebo odstranění. Když například kliknete na tlačítko Upravit v upravitelném objektu GridView, hodnoty záznamů se načtou z databáze a zobrazí se v textových polích a dalších webových ovládacích prvcích. Tyto původní hodnoty jsou uloženy GridView. Později poté, co uživatel provede změny a klikne na tlačítko Aktualizovat, UPDATE musí použitý příkaz vzít v úvahu původní hodnoty a nové hodnoty a aktualizovat podkladový databázový záznam pouze v případě, že původní hodnoty, které uživatel začal upravovat, jsou identické s hodnotami, které jsou stále v databázi. Obrázek 3 znázorňuje tuto posloupnost událostí.

Aby aktualizace nebo odstranění proběhly úspěšně, původní hodnoty musí být stejné jako aktuální hodnoty databáze.

Obrázek 3: Aby aktualizace nebo odstranění proběhly úspěšně, původní hodnoty musí být stejné jako aktuální hodnoty databáze (kliknutím zobrazíte obrázek v plné velikosti)

Existují různé přístupy k implementaci optimistické souběžnosti (podívejte se na několik možností v článku Logika aktualizace optimistické souběžnostiPetera A. Bromberga). Technika, kterou používá SqlDataSource (stejně jako ADO.NET Typed DataSets používané v naší vrstvě přístupu k datůmWHERE) rozšiřuje klauzuli tak, aby zahrnovala porovnání všech původních hodnot. Následující UPDATE příkaz například aktualizuje název a cenu produktu pouze v případě, že aktuální hodnoty databáze jsou rovny hodnotám, které byly původně načteny při aktualizaci záznamu v GridView. Parametry @ProductName a @UnitPrice obsahují nové hodnoty zadané uživatelem, zatímco @original_ProductName a @original_UnitPrice obsahují hodnoty, které byly původně načteny do GridView při kliknutí na tlačítko Upravit:

UPDATE Products SET
    ProductName = @ProductName,
    UnitPrice = @UnitPrice
WHERE
    ProductID = @original_ProductID AND
    ProductName = @original_ProductName AND
    UnitPrice = @original_UnitPrice

Jak uvidíme v tomto kurzu, povolení optimistického řízení souběžnosti pomocí SqlDataSource je stejně jednoduché jako zaškrtnutí políčka.

Krok 1: Vytvoření zdroje dat Sql, který podporuje optimistickou souběžnost

Začněte otevřením OptimisticConcurrency.aspx stránky ze SqlDataSource složky . Přetáhněte ovládací prvek SqlDataSource z panelu nástrojů na Designer a jeho vlastnost na ProductsDataSourceWithOptimisticConcurrencyhodnotu ID . Potom klikněte na odkaz Konfigurovat zdroj dat z inteligentní značky ovládacího prvku. Na první obrazovce průvodce zvolte, jestli chcete pracovat s NORTHWINDConnectionString a klikněte na Další.

Volba práce s připojovacím řetězcem NORTHWINDConnectionString

Obrázek 4: Volba pro práci s NORTHWINDConnectionString (kliknutím zobrazíte obrázek v plné velikosti)

V tomto příkladu přidáme GridView, který uživatelům umožní upravovat Products tabulku. Proto na obrazovce Konfigurovat příkaz Select zvolte Products tabulku z rozevíracího seznamu a vyberte ProductIDsloupce , ProductName, UnitPricea Discontinued , jak je znázorněno na obrázku 5.

Z tabulky Products vraťte sloupce ProductID, ProductName, UnitPrice a Discontinued.

Obrázek 5: Z Products tabulky vraťte ProductIDsloupce , ProductName, UnitPricea Discontinued (kliknutím zobrazíte obrázek v plné velikosti)

Po výběru sloupců kliknutím na tlačítko Upřesnit zobrazte dialogové okno Rozšířené možnosti generování SQL. Zaškrtněte políčka Generovat INSERTpříkazy , UPDATEa DELETE a Použít optimistickou souběžnost a klikněte na OK (snímek obrazovky najdete na obrázku 1). Dokončete průvodce kliknutím na Další a pak na Dokončit.

Po dokončení průvodce Konfigurací zdroje dat se chvíli podívejte na výsledné DeleteCommand vlastnosti a UpdateCommandDeleteParameters kolekce a UpdateParameters . Nejjednodušší způsob, jak to udělat, je kliknout na kartu Zdroj v levém dolním rohu a zobrazit deklarativní syntaxi stránky. Tady najdete UpdateCommand hodnotu:

UPDATE [Products] SET
     [ProductName] = @ProductName,
     [UnitPrice] = @UnitPrice,
     [Discontinued] = @Discontinued
WHERE
     [ProductID] = @original_ProductID AND
     [ProductName] = @original_ProductName AND
     [UnitPrice] = @original_UnitPrice AND
     [Discontinued] = @original_Discontinued

Se sedmi parametry v kolekci UpdateParameters :

<asp:SqlDataSource ID="ProductsDataSourceWithOptimisticConcurrency"
    runat="server" ...>
    <DeleteParameters>
      ...
    </DeleteParameters>
    <UpdateParameters>
        <asp:Parameter Name="ProductName" Type="String" />
        <asp:Parameter Name="UnitPrice" Type="Decimal" />
        <asp:Parameter Name="Discontinued" Type="Boolean" />
        <asp:Parameter Name="original_ProductID" Type="Int32" />
        <asp:Parameter Name="original_ProductName" Type="String" />
        <asp:Parameter Name="original_UnitPrice" Type="Decimal" />
        <asp:Parameter Name="original_Discontinued" Type="Boolean" />
    </UpdateParameters>
    ...
</asp:SqlDataSource>

Podobně DeleteCommand by vlastnost a DeleteParameters kolekce měly vypadat takto:

DELETE FROM [Products]
WHERE
     [ProductID] = @original_ProductID AND
     [ProductName] = @original_ProductName AND
     [UnitPrice] = @original_UnitPrice AND
     [Discontinued] = @original_Discontinued
<asp:SqlDataSource ID="ProductsDataSourceWithOptimisticConcurrency"
    runat="server" ...>
    <DeleteParameters>
        <asp:Parameter Name="original_ProductID" Type="Int32" />
        <asp:Parameter Name="original_ProductName" Type="String" />
        <asp:Parameter Name="original_UnitPrice" Type="Decimal" />
        <asp:Parameter Name="original_Discontinued" Type="Boolean" />
    </DeleteParameters>
    <UpdateParameters>
        ...
    </UpdateParameters>
    ...
</asp:SqlDataSource>

Kromě rozšíření WHERE klauzulí UpdateCommand vlastností a DeleteCommand (a přidání dalších parametrů do příslušných kolekcí parametrů) upravíte výběrem možnosti Použít optimistickou souběžnost dvě další vlastnosti:

Když datový web ovládací prvek vyvolá SqlDataSource s Update() nebo Delete() metodu, předá původní hodnoty. Pokud je vlastnost SqlDataSource s nastavená ConflictDetection na CompareAllValueshodnotu , přidají se do příkazu tyto původní hodnoty. Vlastnost OldValuesParameterFormatString poskytuje vzor pojmenování použitý pro tyto parametry původní hodnoty. Průvodce konfigurovat zdroj dat používá original_{0} a pojmenuje každý původní parametr ve UpdateCommand vlastnostech UpdateParameters a kolekcích a DeleteParametersDeleteCommand odpovídajícím způsobem.

Poznámka

Vzhledem k tomu, že nepoužíváme možnosti vkládání ovládacích prvků SqlDataSource, můžete odebrat vlastnost a její InsertParameters kolekciInsertCommand.

Správné zpracováníNULLhodnot

Rozšířené UPDATE příkazy a DELETE automaticky generované průvodcem Konfigurovat zdroj dat při použití optimistické souběžnosti bohužel nefungují se záznamy, které obsahují NULL hodnoty. Pokud chcete zjistit proč, zvažte naše služby SqlDataSource UpdateCommand:

UPDATE [Products] SET
     [ProductName] = @ProductName,
     [UnitPrice] = @UnitPrice,
     [Discontinued] = @Discontinued
WHERE
     [ProductID] = @original_ProductID AND
     [ProductName] = @original_ProductName AND
     [UnitPrice] = @original_UnitPrice AND
     [Discontinued] = @original_Discontinued

Sloupec UnitPrice v tabulce Products může obsahovat NULL hodnoty. Pokud má NULL konkrétní záznam hodnotu pro UnitPrice, WHERE část [UnitPrice] = @original_UnitPrice klauzule se vždy vyhodnotí jako False, protože NULL = NULL vždy vrátí hodnotu False. Záznamy NULL obsahující hodnoty proto nelze upravovat ani odstraňovat, protože UPDATE klauzule příkazů a DELETE nevrátí žádné řádky WHERE pro aktualizaci nebo odstranění.

Poznámka

Tato chyba byla společnosti Microsoft poprvé oznámena v červnu 2004 v tématu SqlDataSource Generuje nesprávné příkazy SQL a je údajně naplánováno, aby byla opravena v příští verzi ASP.NET.

Abychom tento problém vyřešili, musíme ručně aktualizovat WHERE klauzule ve vlastnostech a UpdateCommandDeleteCommand pro všechny sloupce, které můžou mít NULL hodnoty. Obecně platí, že změňte [ColumnName] = @original_ColumnName na:

(
   ([ColumnName] IS NULL AND @original_ColumnName IS NULL)
     OR
   ([ColumnName] = @original_ColumnName)
)

Tuto úpravu lze provést přímo prostřednictvím deklarativního kódu, prostřednictvím možností UpdateQuery nebo DeleteQuery z okno Vlastnosti nebo prostřednictvím karet UPDATE a DELETE v možnosti Zadat vlastní příkaz SQL nebo uloženou proceduru v průvodci Konfigurovat zdroj dat. Tato změna musí být provedena pro každý sloupec v klauzuli UpdateCommand a DeleteCommand s WHERE , který může obsahovat NULL hodnoty.

Použití tohoto v našem příkladu má za následek následující změněné UpdateCommand hodnoty a DeleteCommand :

UPDATE [Products] SET
     [ProductName] = @ProductName,
     [UnitPrice] = @UnitPrice,
     [Discontinued] = @Discontinued
WHERE
     [ProductID] = @original_ProductID AND
     [ProductName] = @original_ProductName AND
     (([UnitPrice] IS NULL AND @original_UnitPrice IS NULL)
        OR ([UnitPrice] = @original_UnitPrice)) AND
     [Discontinued] = @original_Discontinued
DELETE FROM [Products]
WHERE
     [ProductID] = @original_ProductID AND
     [ProductName] = @original_ProductName AND
     (([UnitPrice] IS NULL AND @original_UnitPrice IS NULL)
        OR ([UnitPrice] = @original_UnitPrice)) AND
     [Discontinued] = @original_Discontinued

Krok 2: Přidání objektu GridView s možnostmi upravit a odstranit

SqlDataSource nakonfigurovaný tak, aby podporoval optimistickou souběžnost, zbývá jen přidat datový webový ovládací prvek na stránku, která využívá tento ovládací prvek souběžnosti. Pro účely tohoto kurzu přidáme Objekt GridView, který poskytuje funkce pro úpravy i odstranění. Chcete-li toho dosáhnout, přetáhněte objekt GridView z panelu nástrojů do Designer a nastavte jeho ID na Products. Z inteligentní značky GridView vytvořte vazbu na ProductsDataSourceWithOptimisticConcurrency ovládací prvek SqlDataSource přidaný v kroku 1. Nakonec zaškrtněte možnosti Povolit úpravy a Povolit odstranění z inteligentní značky.

Vytvoření vazby GridView na SqlDataSource a povolení úprav a odstranění

Obrázek 6: Vytvoření vazby objektu GridView na SqlDataSource a povolení úprav a odstranění (kliknutím zobrazíte obrázek v plné velikosti)

Po přidání objektu GridView nakonfigurujte jeho vzhled odebráním ProductID BoundField, změnou ProductName vlastnosti BoundField s HeaderText na Product a aktualizací UnitPrice BoundField tak, aby jeho HeaderText vlastnost byla jednoduše Price. V ideálním případě bychom vylepšili rozhraní pro úpravy tak, aby obsahovalo RequiredFieldValidator pro ProductName hodnotu a CompareValidator pro UnitPrice hodnotu (aby se zajistilo, že se jedná o správně naformátovanou číselnou hodnotu). Podrobnější informace o přizpůsobení rozhraní pro úpravy gridview najdete v kurzu Přizpůsobení rozhraní pro úpravu dat .

Poznámka

Stav zobrazení GridView s musí být povolen, protože původní hodnoty předané z Objekt GridView do SqlDataSource jsou uloženy ve stavu zobrazení.

Po provedení těchto úprav objektu GridView by deklarativní značky GridView a SqlDataSource měly vypadat podobně jako následující:

<asp:SqlDataSource ID="ProductsDataSourceWithOptimisticConcurrency"
    runat="server" ConflictDetection="CompareAllValues"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    DeleteCommand=
        "DELETE FROM [Products]
         WHERE [ProductID] = @original_ProductID
         AND [ProductName] = @original_ProductName
         AND (([UnitPrice] IS NULL AND @original_UnitPrice IS NULL)
              OR ([UnitPrice] = @original_UnitPrice))
         AND [Discontinued] = @original_Discontinued"
    OldValuesParameterFormatString=
        "original_{0}"
    SelectCommand=
        "SELECT [ProductID], [ProductName], [UnitPrice], [Discontinued]
         FROM [Products]"
    UpdateCommand=
        "UPDATE [Products]
         SET [ProductName] = @ProductName, [UnitPrice] = @UnitPrice,
            [Discontinued] = @Discontinued
         WHERE [ProductID] = @original_ProductID
         AND [ProductName] = @original_ProductName
         AND (([UnitPrice] IS NULL AND @original_UnitPrice IS NULL)
            OR ([UnitPrice] = @original_UnitPrice))
        AND [Discontinued] = @original_Discontinued">
    <DeleteParameters>
        <asp:Parameter Name="original_ProductID" Type="Int32" />
        <asp:Parameter Name="original_ProductName" Type="String" />
        <asp:Parameter Name="original_UnitPrice" Type="Decimal" />
        <asp:Parameter Name="original_Discontinued" Type="Boolean" />
    </DeleteParameters>
    <UpdateParameters>
        <asp:Parameter Name="ProductName" Type="String" />
        <asp:Parameter Name="UnitPrice" Type="Decimal" />
        <asp:Parameter Name="Discontinued" Type="Boolean" />
        <asp:Parameter Name="original_ProductID" Type="Int32" />
        <asp:Parameter Name="original_ProductName" Type="String" />
        <asp:Parameter Name="original_UnitPrice" Type="Decimal" />
        <asp:Parameter Name="original_Discontinued" Type="Boolean" />
    </UpdateParameters>
</asp:SqlDataSource>
<asp:GridView ID="Products" runat="server"
    AutoGenerateColumns="False" DataKeyNames="ProductID"
    DataSourceID="ProductsDataSourceWithOptimisticConcurrency">
    <Columns>
        <asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="Price"
            SortExpression="UnitPrice" />
        <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
            SortExpression="Discontinued" />
    </Columns>
</asp:GridView>

Pokud chcete zobrazit ovládací prvek optimistické souběžnosti v akci, otevřete dvě okna prohlížeče a načtěte OptimisticConcurrency.aspx stránku v obou. Klikněte na tlačítka Upravit u prvního produktu v obou prohlížečích. V jednom prohlížeči změňte název produktu a klikněte na Aktualizovat. Prohlížeč se vrátí zpět a GridView se vrátí do režimu před úpravami a zobrazí nový název produktu právě upraveného záznamu.

V druhém okně prohlížeče změňte cenu (ale ponechte název produktu jako původní hodnotu) a klikněte na Aktualizovat. Při postbacku se mřížka vrátí do režimu před úpravami, ale změna ceny se nezaznamená. Ve druhém prohlížeči se zobrazí stejná hodnota jako u prvního názvu nového produktu se starou cenou. Změny provedené v druhém okně prohlížeče byly ztraceny. Změny se navíc ztratily poměrně tiše, protože se nenašla žádná výjimka nebo zpráva, které by naznačovaly, že právě došlo k narušení souběžnosti.

Změny v druhém okně prohlížeče byly bezobslužně ztraceny.

Obrázek 7: Změny v druhém okně prohlížeče byly bezobslužně ztraceny (kliknutím zobrazíte obrázek v plné velikosti)

Důvodem, proč nebyly potvrzeny druhé změny prohlížeče, bylo to, že UPDATE klauzule s příkazu WHERE vyfiltrovala všechny záznamy, a proto neovlivnila žádné řádky. Podívejme se znovu na UPDATE příkaz:

UPDATE [Products] SET
     [ProductName] = @ProductName,
     [UnitPrice] = @UnitPrice,
     [Discontinued] = @Discontinued
WHERE
     [ProductID] = @original_ProductID AND
     [ProductName] = @original_ProductName AND
     (([UnitPrice] IS NULL AND @original_UnitPrice IS NULL) OR
        ([UnitPrice] = @original_UnitPrice)) AND
     [Discontinued] = @original_Discontinued

Když druhé okno prohlížeče aktualizuje záznam, původní název produktu zadaný v WHERE klauzuli neodpovídá existujícímu názvu produktu (protože ho změnil první prohlížeč). [ProductName] = @original_ProductName Příkaz proto vrátí hodnotu False a nemá vliv na UPDATE žádné záznamy.

Poznámka

Odstranění funguje stejným způsobem. Když jsou otevřená dvě okna prohlížeče, začněte úpravou daného produktu v jednom a uložením jeho změn. Po uložení změn v jednom prohlížeči klikněte na tlačítko Odstranit pro stejný produkt v druhém prohlížeči. Vzhledem k tomu, že původní hodnoty se neshodovaly v klauzuli DELETE s příkazu WHERE , odstranění bezobslužně selže.

Z pohledu koncového uživatele v druhém okně prohlížeče se po kliknutí na tlačítko Aktualizovat mřížka vrátí do režimu před úpravami, ale jejich změny byly ztraceny. Neexistuje ale žádná vizuální zpětná vazba, že se jejich změny nelepily. V ideálním případě platí, že pokud dojde ke ztrátě změn uživatele kvůli narušení souběžnosti, upozorníme ho a třeba mřížku ponecháme v režimu úprav. Pojďme se podívat, jak toho dosáhnout.

Krok 3: Určení, kdy došlo k narušení souběžnosti

Vzhledem k tomu, že porušení souběžnosti odmítne provedené změny, bylo by vhodné upozornit uživatele, když dojde k narušení souběžnosti. Chcete-li uživatele upozornit, přidejte do horní části stránky ovládací prvek Label Web, ConcurrencyViolationMessage jehož Text vlastnost zobrazí následující zprávu: Pokusili jste se aktualizovat nebo odstranit záznam, který byl současně aktualizován jiným uživatelem. Zkontrolujte změny jiného uživatele a pak aktualizaci zopakujte nebo odstraňte. Nastavte vlastnost ovládacího prvku Popisek na CssClass Warning, což je třída CSS definovaná v Styles.css , která zobrazuje text červeným, kurzívou, tučným a velkým písmem. Nakonec nastavte vlastnosti Popisky Visible a EnableViewState na Falsehodnotu . Tím se popisek skryje s výjimkou pouze těch, u kterých jsme explicitně nastavili jeho Visible vlastnost na True.

Přidání ovládacího prvku Popisek na stránku pro zobrazení upozornění

Obrázek 8: Přidání ovládacího prvku Popisek na stránku pro zobrazení upozornění (kliknutím zobrazíte obrázek v plné velikosti)

Při provádění aktualizace nebo odstranění se objekty GridView RowUpdated a RowDeleted obslužné rutiny událostí aktivují poté, co jeho ovládací prvek zdroje dat provedl požadovanou aktualizaci nebo odstranění. Z těchto obslužných rutin událostí můžeme určit, kolik řádků bylo touto operací ovlivněno. Pokud by to ovlivnilo nula řádků, chceme zobrazit ConcurrencyViolationMessage popisek.

Vytvořte obslužnou rutinu RowUpdated události pro události a RowDeleted a přidejte následující kód:

Protected Sub Products_RowUpdated(sender As Object, e As GridViewUpdatedEventArgs) _
    Handles Products.RowUpdated
    If e.AffectedRows = 0 Then
        ConcurrencyViolationMessage.Visible = True
        e.KeepInEditMode = True
        ' Rebind the data to the GridView to show the latest changes
        Products.DataBind()
    End If
End Sub
Protected Sub Products_RowDeleted(sender As Object, e As GridViewDeletedEventArgs) _
    Handles Products.RowDeleted
    If e.AffectedRows = 0 Then
        ConcurrencyViolationMessage.Visible = True
    End If
End Sub

V obou obslužných rutinách událostí zkontrolujeme e.AffectedRows vlastnost a pokud se rovná 0, nastavte ConcurrencyViolationMessage vlastnost Popisek na TrueVisible . V obslužné rutině RowUpdated události také dáváme objektu GridView pokyn, aby zůstal v režimu úprav nastavením KeepInEditMode vlastnosti true. Přitom musíme data znovu připojit k mřížce, aby se data ostatních uživatelů načetla do rozhraní pro úpravy. Toho je dosaženo voláním metody GridView s DataBind() .

Jak ukazuje obrázek 9, u těchto dvou obslužných rutin událostí se při každém porušení souběžnosti zobrazí velmi nápadná zpráva.

Zpráva se zobrazí tváří v tvář porušení souběžnosti.

Obrázek 9: Zpráva je zobrazena v obličeji porušení souběžnosti (kliknutím zobrazíte obrázek v plné velikosti)

Souhrn

Při vytváření webové aplikace, ve které může stejná data upravovat více souběžných uživatelů, je důležité zvážit možnosti řízení souběžnosti. Ve výchozím nastavení webové ovládací prvky ASP.NET dat a ovládací prvky zdroje dat nepoužívají žádné řízení souběžnosti. Jak jsme viděli v tomto kurzu, implementace optimistického řízení souběžnosti pomocí SqlDataSource je poměrně rychlá a snadná. SqlDataSource zpracovává většinu legwork pro přidání rozšířených WHERE klauzulí do automaticky vygenerovaných UPDATE a příkazů, DELETE ale existuje několik jemností ve zpracování NULL sloupců hodnot, jak je popsáno v části Správné zpracování NULL hodnot.

Tento kurz zakončí naše zkoumání SqlDataSource. Zbývající kurzy se vrátí k práci s daty pomocí ObjectDataSource a vrstvené architektury.

Šťastné programování!

O autorovi

Scott Mitchell, autor sedmi knih o ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, školitel a spisovatel. Jeho nejnovější kniha je Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Můžete ho najít na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím jeho blogu, který najdete na http://ScottOnWriting.NETadrese .