Poznámka
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
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 poskytnout tyto funkce, potřebovali jsme ve vlastnostech ovládacího prvku určit odpovídající příkaz SQL INSERT
, UPDATE
nebo DELETE
spolu s příslušnými parametry v kolekcích InsertParameters
, UpdateParameters
a DeleteParameters
. I když je možné tyto vlastnosti a kolekce zadat ručně, průvodce Konfigurovat zdroj dat tlačítkem Upřesnit nabízí zaškrtávací políčko Generovat INSERT
, UPDATE
, a DELETE
příkazy, které automaticky vytvoří tyto příkazy založené na příkazu SELECT
.
Kromě zaškrtávacího políčka Generovat INSERT
, UPDATE
a DELETE
příkazy obsahuje dialogové okno Pokročilé možnosti generování SQL volbu Používat optimistickou souběžnost (viz obrázek 1). Když je zaškrtnuto, klauzule v automaticky vygenerovaných UPDATE
a DELETE
příkazech se upraví tak, aby prováděly pouze aktualizaci nebo odstranění, pokud se podkladová data databáze od posledního načtení dat uživatelem do mřížky nezměnila.
Obrázek 1: Podporu optimistické souběžnosti můžete přidat pomocí dialogového okna Pokročilé možnosti generování SQL
Zpátky v kurzu Implementace optimistické souběžnosti jsme prozkoumali základy optimistického řízení souběžnosti a jak ho přidat do ObjectDataSource. V tomto kurzu si probereme 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 může omylem přepsat jiné změny. V tutoriálu Implementace optimistické souběžnosti jsem poskytl 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žnila aktualizovat a odstranit produkty prostřednictvím ovládacího prvku GridView. Oba ve stejnou dobu kliknou na tlačítko Upravit pro Chai. Jisun změní název produktu na Chai Tea a klikne na tlačítko Aktualizovat. Čistý výsledek je UPDATE
příkaz odeslaný 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 hodnoty Chai Tea, kategorii Nápoje, dodavatele Exotic Liquids a tak dále pro tento konkrétní produkt. GridView na Samově obrazovce ale stále zobrazuje název produktu v řádku GridView, který lze upravovat, jako Chai. Několik sekund po provedení změn Jisunu Sam aktualizuje kategorii na dochucovadla 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 Koření a tak dále. Změny, které Jisun provedla v názvu produktu, byly přepsány.
Obrázek 2 znázorňuje tuto interakci.
Obrázek 2: Když dva uživatelé současně aktualizují záznam, může dojít ke změně jednoho uživatele, aby přepsal ostatní (kliknutím zobrazíte obrázek v plné velikosti).
Aby k tomuto scénáři nedošlo, musí být implementována forma řízení souběžnosti. Optimistická souběžnost, na kterou se tento tutoriál zaměřuje, funguje na předpokladu, že i když může čas od času dojít ke konfliktům souběžnosti, ve velké 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 jejich změny nelze uložit, protože jiný uživatel změnil 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é, můžete 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 .
Optimistické řízení souběžnosti funguje tak, že zajišťuje, aby záznam, který se aktualizuje nebo odstranil, měl stejné hodnoty jako při spuštění aktualizace nebo odstranění procesu. Když například kliknete na tlačítko Upravit v upravitelném objektu GridView, hodnoty záznamů se č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 objektem GridView. Později, když uživatel provede změny a klikne na tlačítko Aktualizovat, musí použitý příkaz vzít v úvahu původní hodnoty a nové hodnoty a aktualizovat pouze podkladový záznam databáze, pokud původní hodnoty, které uživatel začal upravovat, UPDATE
jsou stejné jako hodnoty stále v databázi. Obrázek 3 znázorňuje tuto posloupnost událostí.
Obrázek 3: Aby aktualizace nebo odstranění byla úspěšná, musí být původní hodnoty rovny aktuálním hodnotám databáze (kliknutím zobrazíte obrázek v plné velikosti).
Existují různé přístupy k implementaci optimistické souběžnosti (viz Peter A. Bromberg's logika aktualizace optimistické souběžnosti pro stručné seznámení s řadou možností). Technika používaná SqlDataSource (a také ADO.NET Typové datové sady používané v naší vrstvě přístupu k datům) rozšiřuje WHERE
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 se aktuální hodnoty databáze rovnají 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 po 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í SqlDataSource, 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ů do Návrháře a nastavte jeho vlastnost ID
na ProductsDataSourceWithOptimisticConcurrency
. Klikněte na odkaz Konfigurovat zdroj dat pomocí inteligentní značky ovládacího prvku. Na první obrazovce v průvodci zvolte, že chcete pracovat s NORTHWINDConnectionString
a klikněte na Další.
Obrázek 4: Volba práce s obrázkem NORTHWINDConnectionString
(kliknutím zobrazíte obrázek s plnou velikostí)
V tomto příkladu přidáme Objekt GridView, který uživatelům umožní tabulku upravit Products
. Proto na obrazovce Konfigurovat příkaz select zvolte Products
tabulku z rozevíracího seznamu a vyberte ProductID
, ProductName
, UnitPrice
a Discontinued
sloupce, jak je znázorněno na obrázku 5.
Obrázek 5: Z Products
tabulky vraťte sloupce ProductID
, ProductName
, UnitPrice
a Discontinued
(kliknutím zobrazíte obrázek v plné velikosti)
Po výběru sloupců kliknutím na tlačítko Upřesnit zobrazíte dialogové okno Upřesnit možnosti generování SQL. Zaškrtněte políčka pro generování příkazů INSERT
, UPDATE
a DELETE
a pro používání optimistické souběžnosti a klikněte na OK (pro snímek obrazovky se vraťte k obrázku 1). Dokončete průvodce kliknutím na Další a poté na Dokončit.
Po dokončení průvodce konfigurací zdroje dat věnujte chvíli kontrole výsledných DeleteCommand
a UpdateCommand
vlastností a DeleteParameters
a UpdateParameters
kolekcí. Nejjednodušší způsob, jak to udělat, je kliknout na kartu Zdroj v levém dolním rohu a zobrazit deklarativní syntaxi stránky. Tam 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
S kolekcí UpdateParameters
obsahující sedm parametrů:
<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ě by DeleteCommand
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
a DeleteCommand
vlastností (a přidání dalších parametrů do příslušných kolekcí parametrů) se výběrem možnosti Použít optimistickou souběžnost upraví dvě další vlastnosti:
-
ConflictDetection
Změní vlastnost zOverwriteChanges
(výchozí) naCompareAllValues
-
OldValuesParameterFormatString
Změní vlastnost z {0} (výchozí) na original_{0} .
Když datový webový ovládací prvek vyvolá SqlDataSource s Update()
nebo Delete()
metodu, předá původní hodnoty. Pokud je vlastnost SqlDataSource ConflictDetection
nastavena na CompareAllValues
, tyto původní hodnoty jsou přidány do příkazu. Vlastnost OldValuesParameterFormatString
poskytuje vzor pojmenování použitý pro tyto původní parametry hodnoty. Průvodce konfigurací zdroje dat používá original_{0} a pojmenuje každý původní parametr v UpdateCommand
a DeleteCommand
vlastnostech a UpdateParameters
a DeleteParameters
kolekcích.
Poznámka:
Protože nepoužíváme možnosti vkládání ovládacího prvku SqlDataSource, můžete odstranit vlastnost InsertCommand
a její kolekci InsertParameters
.
Správné zpracováníNULL
hodnot
Bohužel rozšířené příkazy UPDATE
a DELETE
, které automaticky vygeneroval průvodce Konfigurovat zdroj dat při použití optimistické souběžnosti, nefungují se záznamy, které obsahují NULL
hodnoty. Pokud chcete zjistit proč, zvažte naše SqlDataSource s 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 Products
tabulce může obsahovat NULL
hodnoty. Pokud má konkrétní záznam NULL
hodnotu UnitPrice
, WHERE
část [UnitPrice] = @original_UnitPrice
klauzule se vždy vyhodnotí jako False, protože NULL = NULL
vždy vrátí hodnotu False. Proto záznamy obsahující NULL
hodnoty nelze upravovat ani odstraňovat, protože UPDATE
klauzule a DELETE
klauzule příkazů nevrací žádné řádky WHERE
pro aktualizaci nebo odstranění.
Poznámka:
Tato chyba byla poprvé hlášena společnosti Microsoft v červnu 2004 v SqlDataSource Generuje nesprávné příkazy SQL a je hlášena, že je naplánována na opravení v další verzi ASP.NET.
Abychom to vyřešili, musíme ručně aktualizovat WHERE
klauzule ve vlastnostech UpdateCommand
a DeleteCommand
pro všechny sloupce, které můžou mít NULL
hodnoty. Obecně platí, že změníte [ColumnName] = @original_ColumnName
na:
(
([ColumnName] IS NULL AND @original_ColumnName IS NULL)
OR
([ColumnName] = @original_ColumnName)
)
Tuto změnu lze provést přímo prostřednictvím deklarativního kódu, prostřednictvím možností UpdateQuery nebo DeleteQuery z okna Vlastnosti nebo prostřednictvím karet UPDATE a DELETE v okně Zadat vlastní příkaz SQL nebo uloženou proceduru v průvodci konfigurací zdroje dat. Tato změna musí být provedena pro každý sloupec v klauzuli UpdateCommand
a DeleteCommand
s WHERE
, které mohou obsahovat NULL
hodnoty.
Použití tohoto příkladu má za následek následující změněné UpdateCommand
hodnoty a DeleteCommand
hodnoty:
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
Když je SqlDataSource nakonfigurovaný tak, aby podporoval optimistickou souběžnost, zbývá už jen přidat webový datový ovládací prvek na stránku, která využívá toto řízení souběžnosti. Pro účely tohoto kurzu přidáme GridView, který poskytuje funkce pro úpravy i odstranění. Chcete-li toho dosáhnout, přetáhněte Objekt GridView ze sady nástrojů do Návrháře a nastavte jej ID
na Products
. Z inteligentní značky GridView ho 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.
Obrázek 6: Vytvoření vazby Objektu GridView k SqlDataSource a povolení úprav a odstranění (kliknutím zobrazíte obrázek s plnou velikostí)
Po přidání GridView nakonfigurujte jeho vzhled odebráním ProductID
BoundField, změnou vlastnosti ProductName
BoundField na Product a aktualizací UnitPrice
BoundField tak, aby jeho vlastnost byla jednoduše Price. V ideálním případě bychom vylepšili rozhraní pro úpravy tak, aby zahrnovalo RequiredFieldValidator pro ProductName
hodnotu a CompareValidator pro UnitPrice
hodnotu (aby se zajistilo, že se jedná o správně formátovanou číselnou hodnotu). Podrobnější informace o přizpůsobení rozhraní pro úpravy dat najdete v kurzu Přizpůsobení rozhraní pro úpravy dat .
Poznámka:
Stav zobrazení GridView s musí být povolen, protože původní hodnoty předané z GridView do SqlDataSource jsou uloženy ve stavu zobrazení.
Po provedení těchto úprav objektu GridView by deklarativní kód GridView a SqlDataSource měl vypadat přibližně takto:
<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 vidět optimistické řízení souběžnosti v akci, otevřete dvě okna prohlížeče a načtěte OptimisticConcurrency.aspx
stránku v obou dvou. V obou prohlížečích klikněte na tlačítka Upravit první produkt. V jednom prohlížeči změňte název produktu a klikněte na Aktualizovat. Prohlížeč provede postback a GridView se vrátí do režimu před úpravami, zobrazí nový název produktu pro právě upravený záznam.
V druhém okně prohlížeče změňte cenu (ale ponechte název produktu jako původní hodnotu) a klikněte na Tlačítko Aktualizovat. Při zpětném odeslání se mřížka přepne zpět do režimu před úpravami, ale změna ceny se nezaznamená. Druhý prohlížeč zobrazuje stejnou hodnotu jako první název nového produktu se starou cenou. Změny provedené v druhém okně prohlížeče byly ztraceny. Změny byly navíc ztraceny dost nenápadně, protože nedošlo k výjimce nebo zprávě oznamující, že došlo k porušení souběžnosti.
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 změny druhého prohlížeče, byla proto, že UPDATE
klauzule s WHERE
příkazu odfiltrovala všechny záznamy, a proto neměla vliv na žádné řádky. Pojďme se znovu podívat 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 se neshoduje s existujícím názvem produktu (protože byl změněn prvním prohlížečem). Proto příkaz [ProductName] = @original_ProductName
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 jedním a uložením změn. Po uložení změn v jednom prohlížeči klikněte na tlačítko Odstranit pro stejný produkt v druhém. Vzhledem k tomu, že v klauzuli DELETE
příkazu WHERE
původní hodnoty neodpovídají, odstranění tiše 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 úpravou, ale jejich změny byly ztraceny. Neexistuje ale žádná vizuální zpětná vazba, která by naznačovala, že jejich změny nebyly přijaty. V ideálním případě, pokud dojde ke ztrátě změn uživatele kvůli porušení souběžnosti, upozorníme uživatele a například necháme mřížku v režimu úprav. Pojďme se podívat, jak toho dosáhnout.
Krok 3: Určení, kdy došlo k poruš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 porušení souběžnosti. Chcete-li upozornit uživatele, pojďme přidat ovládací prvek Label Web na začátek stránky, ConcurrencyViolationMessage
jejíž Text
vlastnost zobrazuje 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 ostatních uživatelů a pak aktualizaci nebo odstranění zopakujte. Nastavte vlastnost ovládacího prvku CssClass
Popisek na "Warning", což je třída CSS definovaná v Styles.css
a zobrazuje text v červené, kurzívou, tučném a velkém písmu. Nakonec nastavte vlastnosti popisků Visible
a EnableViewState
na hodnotu False
. Tím se skryje popisek s výjimkou těch postbacků, kde jsme explicitně nastavili jeho vlastnost Visible
na True
.
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 gridView s RowUpdated
a RowDeleted
obslužné rutiny událostí aktivují po provedení požadované aktualizace nebo odstranění ovládacího prvku zdroje dat. Z těchto obslužných rutin událostí můžeme určit, kolik řádků operace ovlivnila. Pokud byly ovlivněny nulové řádky, chceme zobrazit ConcurrencyViolationMessage
popisek.
Vytvořte obslužnou rutinu události pro RowUpdated
události i RowDeleted
události 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í kontrolujeme vlastnost e.AffectedRows
a pokud se rovná 0, nastavíme vlastnost Visible
u ConcurrencyViolationMessage
na True
. V obslužné rutině RowUpdated
události také dáváme pokyn GridView, aby zůstal v režimu úprav nastavením vlastnosti KeepInEditMode
na true. V takovém případě potřebujeme data znovu připojit k mřížce tak, aby se do rozhraní pro úpravy načetla data ostatních uživatelů. Toho se dosahuje voláním Metody GridView s DataBind()
.
Jak ukazuje obrázek 9, s těmito dvěma obslužnými rutinami událostí se při výskytu porušení souběžnosti zobrazí velmi znatelná zpráva.
Obrázek 9: Při porušení souběžnosti se zobrazí zpráva (kliknutím zobrazíte obrázek v plné velikosti).
Shrnutí
Při vytváření webové aplikace, kde může několik souběžných uživatelů upravovat stejná data, 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 práce související s přidáním rozšířených WHERE
klauzulí do automaticky vygenerovaných UPDATE
a DELETE
příkazů, ale existují některé jemnosti při zpracování NULL
sloupců hodnot, jak je popsáno v části Správné zpracování hodnot NULL
.
V tomto kurzu se dokončí 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 ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, trenér a spisovatel. Jeho nejnovější kniha je Sams Naučte se ASP.NET 2.0 v 24 hodinách. Může být dosažitelný na mitchell@4GuysFromRolla.comadrese .