Megosztás a következőn keresztül:


Optimista egyidejűség implementálása az SqlDataSource -nal (VB)

által Scott Mitchell

PDF letöltése

Ebben az oktatóanyagban áttekintjük az optimista egyidejűség-vezérlés alapjait, majd megismerjük, hogyan implementálható az SqlDataSource vezérlővel.

Bevezetés

Az előző oktatóanyagban megvizsgáltuk, hogyan adhat hozzá beszúrási, frissítési és törlési képességeket az SqlDataSource vezérlőhöz. Röviden: ezeknek a funkcióknak a biztosításához meg kellett adni a megfelelő INSERT, UPDATE vagy DELETE SQL-utastást a vezérlő InsertCommand, UpdateCommand vagy DeleteCommand tulajdonságaiban, valamint a megfelelő paramétereket a InsertParameters, UpdateParameters és DeleteParameters gyűjteményekben. Bár ezeket a tulajdonságokat és gyűjteményeket manuálisan is meg lehet adni, az Adatforrás konfigurálása varázsló Speciális gombja egy Létrehozás INSERT, UPDATE és DELETE utasításokat tartalmazó jelölőnégyzetet biztosít, amely automatikusan létrehozza ezeket az utasításokat az SELECT utasítás alapján.

A INSERT, UPDATE és DELETE utasítások létrehozásának jelölőnégyzete mellett a Speciális SQL-generálási beállítások párbeszédpanelen van egy Optimista egyidejűség használata opció (lásd az 1. ábrát). Ha be van jelölve, a WHERE az automatikusan létrehozott UPDATE és DELETE utasításokban lévő záradékok úgy módosulnak, hogy a frissítést vagy törlést csak akkor hajtják végre, ha a mögöttes adatbázis adatai nem módosultak azóta, hogy a felhasználó legutóbb betöltötte az adatokat a táblázatba.

Optimista egyidejűségi támogatást a Speciális SQL-létrehozási beállítások párbeszédpanelen adhat hozzá

1. ábra: Optimista egyidejűségi támogatást adhat hozzá a Speciális SQL-létrehozási beállítások párbeszédpanelről

A Implementing Optimistic Concurrency oktatóanyagban megvizsgáltuk az optimista egyidejűség-vezérlés alapjait, és azt, hogyan lehet azt hozzáadni az ObjectDataSource-hoz. Ebben az oktatóanyagban újra átnézzük az optimista egyidejűség-vezérlés alapjait, majd megismerjük, hogyan lehet megvalósítani az SqlDataSource használatával.

Az optimista együttműködési értékelés

Az olyan webalkalmazások esetében, amelyek lehetővé teszik, hogy több egyidejű felhasználó szerkessze vagy törölje ugyanazokat az adatokat, fennáll annak a lehetősége, hogy egy felhasználó véletlenül felülír egy másik módosítást. Az Optimista egyidejűség megvalósítása oktatóanyagban a következő példát mutattam be:

Tegyük fel, hogy két felhasználó, Jisun és Sam is meglátogatott egy oldalt egy alkalmazásban, amely lehetővé tette a látogatók számára a termékek frissítését és törlését egy GridView-vezérlőn keresztül. Mindketten körülbelül ugyanabban az időben kattintanak a Chai szerkesztés gombjára. Jisun megváltoztatja a termék nevét Chai Tea, és kattintson a Frissítés gombra. A nettó eredmény egy UPDATE utasítás, amelyet elküldenek az adatbázisba, és amely beállítja a termék összes frissíthető mezőjét (annak ellenére, hogy Jisun csak egy mezőt frissített, ProductName). Jelenleg az adatbázis a Chai Tea, az Italok kategória, az Exotic Liquids szállító stb. értékekkel rendelkezik az adott termékhez. A Sam-képernyőn látható GridView azonban továbbra is Chaiként jeleníti meg a termék nevét a szerkeszthető GridView sorban. Néhány másodperccel Jisun módosításainak véglegesítése után Sam frissíti a kategóriát a Condimentsre, és a Frissítés gombra kattint. Ez egy olyan UPDATE utasítást eredményez, amelyet az adatbázisba küldenek, és ami a termék nevét Chai-ra állítja be, a CategoryID pedig a megfelelő Fűszerek kategóriaazonosítóra stb. Jisun módosításait felülírták a terméknévre.

A 2. ábra ezt az interakciót szemlélteti.

Ha két felhasználó egyszerre frissít egy rekordot, akkor lehetséges, hogy az egyik felhasználó módosítja a másikat

2. ábra: Ha két felhasználó egyidejűleg frissít egy rekordot, lehetséges, hogy az egyik felhasználó módosítja a másikat (kattintson ide a teljes méretű kép megtekintéséhez)

A forgatókönyv kibontakozásának megakadályozása érdekében az egyidejűség-vezérlés egy formáját kell implementálnia. Optimista egyidejűség az oktatóanyag középpontjában azon a feltételezésen alapul, hogy bár időnként egyidejűségi ütközések fordulhatnak elő, az ilyen ütközések túlnyomó többsége nem fog bekövetkezni. Ezért ütközés esetén az optimista egyidejűség-vezérlés egyszerűen tájékoztatja a felhasználót arról, hogy a módosítások nem menthetők, mert egy másik felhasználó módosította ugyanazokat az adatokat.

Megjegyzés:

Az olyan alkalmazások esetében, ahol feltételezik, hogy sok egyidejűségi ütközés lesz, vagy ha az ilyen ütközések nem tolerálhatók, akkor pesszimista egyidejűség-vezérlés használható helyette. A pesszimista egyidejűség-vezérlésről bővebben az Optimista egyidejűség implementálási oktatóanyagában olvashat.

Az optimista egyidejűség-vezérlés úgy működik, hogy a frissített vagy törölt rekord értékei megegyeznek a frissítési vagy törlési folyamat indításakor megadott értékekkel. Ha például a Szerkeszthető gombra kattint egy szerkeszthető GridView-ban, a rendszer beolvassa a rekord s értékeit az adatbázisból, és megjelenik a Szövegdobozokban és más webes vezérlőkben. Ezeket az eredeti értékeket a GridView menti. Később, miután a felhasználó végrehajtotta a módosításokat, és a Frissítés gombra kattintott, a UPDATE használt utasításnak figyelembe kell vennie az eredeti értékeket és az új értékeket, és csak akkor kell frissítenie az alapul szolgáló adatbázisrekordot, ha a felhasználó által megkezdett eredeti értékek megegyeznek az adatbázisban lévő értékekkel. A 3. ábra az események sorozatát ábrázolja.

Ahhoz, hogy a frissítés vagy a törlés sikeres legyen, az eredeti értékeknek meg kell egyezniük az aktuális adatbázisértékekkel

3. ábra: Ahhoz, hogy a frissítés vagy a törlés sikeres legyen, az eredeti értékeknek meg kell egyezniük az aktuális adatbázisértékekkel (kattintson ide a teljes méretű kép megtekintéséhez)

Az optimista egyidejűség megvalósításának különböző megközelítései vannak (néhány lehetőség rövid áttekintéséért lásd Peter A. Brombergoptimista egyidejűségi frissítési logikáját ). Az SqlDataSource által használt technika (valamint az adatelérési rétegben használt ADO.NET típusú adathalmazok) kibővíti a WHERE záradékot, hogy az összes eredeti érték összehasonlítását tartalmazza. Az alábbi UPDATE utasítás például csak akkor frissíti egy termék nevét és árát, ha az adatbázis aktuális értékei megegyeznek a GridView rekordjának frissítésekor eredetileg lekért értékekkel. A @ProductName paraméterek tartalmazzák @UnitPrice a felhasználó által megadott új értékeket, míg @original_ProductName@original_UnitPrice a Szerkesztés gombra kattintáskor eredetileg betöltött értékeket a GridView-ba:

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

Ahogy az oktatóanyagban látható, az optimista egyidejűség-vezérlés engedélyezése az SqlDataSource-nal ugyanolyan egyszerű, mint egy jelölőnégyzet ellenőrzése.

1. lépés: Optimista egyidejűséget támogató SqlDataSource létrehozása

Először nyissa meg a OptimisticConcurrency.aspx lapot a SqlDataSource mappából. Húzzon egy SqlDataSource-vezérlőt az eszközkészletből a Tervezőre, majd állítsa be a ID tulajdonságát ProductsDataSourceWithOptimisticConcurrency értékre. Ezután kattintson az Adatforrás konfigurálása hivatkozásra a vezérlő intelligens címkéjén. A varázsló első képernyőjén válassza ki a NORTHWINDConnectionString opciót, és kattintson a Tovább gombra.

Válassza a NORTHWINDConnectionString használatát

4. ábra: Válassza ki a munkában való részvételt (NORTHWINDConnectionString)

Ebben a példában egy GridView-t adunk hozzá, amely lehetővé teszi a felhasználók számára a tábla szerkesztését Products . Ezért a Konfigurálási utasítás képernyőn válassza ki a Products táblázatot a legördülő listából, és válassza ki a ProductID, ProductName, UnitPriceés Discontinued oszlopokat az 5. ábrán látható módon.

A Termékek táblából adja vissza a ProductID, a ProductName, a UnitPrice és a Megszűnt oszlopokat

5. ábra: A táblázatból adja vissza a ProductsProductID, ProductName, UnitPriceés Discontinued oszlopokat (ide kattintva megtekintheti a teljes méretű képet)

Az oszlopok kiválasztása után kattintson a Speciális gombra a Speciális SQL-létrehozási beállítások párbeszédpanel megjelenítéséhez. Ellenőrizze a Létrehozás INSERT, UPDATE és DELETE utasításokat, valamint az Optimista párhuzamossági jelölőnégyzetet, majd kattintson az OK gombra (képernyőképért tekintse meg az 1. ábrát). A varázsló befejezéséhez kattintson a Tovább, majd a Befejezés gombra.

Az Adatforrás konfigurálása varázsló befejezése után szánjon egy kis időt az eredményül kapott DeleteCommand és UpdateCommand tulajdonságok, valamint a DeleteParameters és UpdateParameters gyűjtemények vizsgálatára. Ennek legegyszerűbb módja, ha a bal alsó sarokban a Forrás fülre kattint, és megtekinti a lap deklaratív szintaxisát. Itt a következő értékeket találja 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

Hét paraméterrel a UpdateParameters gyűjteményben:

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

Hasonlóképpen, a DeleteCommand tulajdonságnak és a DeleteParameters gyűjteménynek a következőképpen kell kinéznie:

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>

Amellett, hogy kibővíti a WHERE tulajdonságok záradékait UpdateCommandDeleteCommand (és hozzáadja a további paramétereket a megfelelő paramétergyűjteményekhez), az Optimista egyidejűség használata beállítás kiválasztásával két másik tulajdonságot is módosít:

Amikor az adat-webvezérlő meghívja az SqlDataSource Update() vagy Delete() metódusát, az eredeti értékeket adja át. Ha az SqlDataSource tulajdonság értéke ConflictDetection be CompareAllValuesvan állítva, ezek az eredeti értékek hozzá lesznek adva a parancshoz. A OldValuesParameterFormatString tulajdonság az eredeti értékparaméterekhez használt elnevezési mintát tartalmazza. Az Adatforrás konfigurálása varázsló original_{0} használ, és ennek megfelelően nevezi el az egyes eredeti paramétereket a UpdateCommandDeleteCommand tulajdonságokban és UpdateParametersDeleteParameters gyűjteményekben.

Megjegyzés:

Mivel nem használjuk az SqlDataSource vezérlő beszúrási képességeit, nyugodtan távolítsa el a InsertCommand tulajdonságot és a InsertParameters gyűjteményét.

Értékek helyes kezeléseNULL

Sajnos az Adatforrás konfigurálása varázsló által az optimista egyidejűség használatakor automatikusan létrehozott bővített UPDATE és DELETE utasítások nem működnek az értékeket tartalmazó NULL rekordokkal. Annak megértése érdekében, hogy miért, vegyük szemügyre az 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

A UnitPrice táblázatban lévő Products oszlopban lehetnek NULL értékek. Ha egy adott rekordnak NULLvan UnitPrice értéke, a WHERE záradékrész [UnitPrice] = @original_UnitPricemindig Hamis értéket ad vissza, mert NULL = NULL mindig Hamis értéket ad vissza. Ezért az olyan rekordok, amelyek NULL értékeket tartalmaznak, nem szerkeszthetők vagy törölhetők, mivel az UPDATE és DELETE utasítások WHERE záradékai nem adnak vissza sorokat frissítéshez vagy törléshez.

Megjegyzés:

Ezt a hibát először 2004 júniusában jelentették a Microsoftnak az SqlDataSource helytelen SQL-utasítások generálása során, és a jelentések szerint a ASP.NET következő verziójában lesz javítva.

A probléma megoldásához manuálisan kell frissítenünk a WHERE záradékokat az UpdateCommand és DeleteCommand tulajdonságokban összes olyan oszlopra, amely rendelkezhet NULL értékekkel. Általában a következőre kell váltani [ColumnName] = @original_ColumnName :

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

Ezt a módosítást közvetlenül a deklaratív korrektúra használatával, a Tulajdonságok ablak UpdateQuery vagy DeleteQuery beállításaival, vagy az Adatforrás konfigurálása varázsló Update és DELETE lapján, az Egyéni SQL-utasítás megadása vagy a tárolt eljárás beállításai között végezheti el. Ezt a módosítást minden olyan oszlopban végre kell hajtani a UpdateCommand és DeleteCommandWHERE záradékban, amely tartalmazhat NULL értékeket.

A példára való alkalmazás eredményeként a következő módosított UpdateCommand és DeleteCommand értékeket kapjuk:

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

2. lépés: GridView hozzáadása szerkesztési és törlési beállításokkal

Az optimista egyidejűség támogatására konfigurált SqlDataSource-nal mindössze egy adat-webvezérlőt kell hozzáadni az egyidejűségi vezérlőt használó laphoz. Ebben az oktatóanyagban adjunk hozzá egy GridView-t, amely szerkesztési és törlési funkciókat is biztosít. Ehhez húzzon egy GridView-t az Eszközkészletből a Tervezőre, és állítsa be a ID értékét Products értékre. A GridView intelligens címkéjében kösse azt az ProductsDataSourceWithOptimisticConcurrency 1. lépésben hozzáadott SqlDataSource-vezérlőhöz. Végül ellenőrizze a Szerkesztés engedélyezése és a Törlés engedélyezése lehetőséget az intelligens címkéről.

A GridView kötése az SqlDataSource-hoz, és szerkesztés és törlés engedélyezése

6. ábra: Kösse a GridView-t az SqlDataSource-hoz, és engedélyezze a szerkesztést és a törlést (kattintson ide a teljes méretű kép megtekintéséhez)

A GridView hozzáadása után konfigurálja a megjelenését a ProductID BoundField eltávolításával, a ProductName BoundField HeaderText tulajdonság termékre való módosításával, valamint a UnitPrice BoundField frissítésével HeaderText , hogy a tulajdonság egyszerűen Price legyen. Ideális esetben a szerkesztőfelületet úgy bővítjük, hogy tartalmazza az ProductName értékhez tartozó RequiredFieldValidatort és az UnitPrice értékhez tartozó CompareValidatort (hogy biztosítsuk, megfelelően formázott numerikus érték legyen). Tekintse meg az Adatmódosítási felület testreszabása oktatóanyagot a GridView szerkesztőfelületének testreszabásával kapcsolatban.

Megjegyzés:

A GridView nézetállapotát engedélyezni kell, mivel a GridView-ból az SqlDataSource-ba átadott eredeti értékek nézetállapotban vannak tárolva.

A GridView módosításainak elvégzése után a GridView és az SqlDataSource deklaratív korrektúra a következőhöz hasonlóan néz ki:

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

Az optimista egyidejűség-vezérlés működés közbeni megtekintéséhez nyisson meg két böngészőablakot, és töltse be a OptimisticConcurrency.aspx lapot mindkettőbe. Kattintson mindkét böngészőben az első termék Szerkesztés gombjára. Egy böngészőben módosítsa a termék nevét, és kattintson a Frissítés gombra. A böngésző visszatér, és a GridView visszatér az előszerkesztési módba, és megjeleníti az imént szerkesztett rekord új terméknevét.

A második böngészőablakban módosítsa az árat (de hagyja meg a termék nevét eredeti értékként), és kattintson a Frissítés gombra. A visszavételkor a táblázat visszaáll a szerkesztési előtti módra, de az árváltozás nem lesz rögzítve. A második böngésző ugyanazt az értéket jeleníti meg, mint az első, az új termék neve a régi áron. A második böngészőablakban végrehajtott módosítások elvesztek. Ezenkívül a módosítások észrevétlenül elvesztek, mivel nem volt kivétel vagy üzenet, amely jelezte, hogy az egyidejűség megsértése éppen most történt.

A második böngészőablak módosításai csendesen elvesztek

7. ábra: A második böngészőablak változásai csendben elvesztek (kattintson ide a teljes méretű kép megtekintéséhez)

A második böngésző változásait azért nem véglegesítették, mert a UPDATE feltétel kiszűrte a WHERE összes rekordot, így nem érintett egyetlen sort sem. Vizsgáljuk meg újra az utasítást UPDATE :

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

Amikor a második böngészőablak frissíti a rekordot, a záradékban WHERE megadott eredeti terméknév nem egyezik meg a meglévő terméknévvel (mivel az első böngésző módosította). Ezért az utasítás [ProductName] = @original_ProductName hamis értéket ad vissza, és a UPDATE rekordokat nem befolyásolja.

Megjegyzés:

A törlés ugyanúgy működik. Ha két böngészőablak nyílik meg, először szerkessze egy adott termék egyikét, majd mentse a módosításokat. Miután mentette a módosításokat az egyik böngészőben, kattintson a Törlés gombra ugyanazon terméknél a másikban. Mivel az eredeti értékek nem egyeznek meg az DELETE utasítás záradékában WHERE , a törlés csendesen meghiúsul.

A végfelhasználó szempontjából a második böngészőablakban a Frissítés gombra kattintás után a rács visszaáll az előszerkesztési módra, de a módosítások elvesztek. Nincs azonban vizuális visszajelzés arról, hogy a módosítások nem ragadtak meg. Ideális esetben, ha egy felhasználó módosításai elvesznek egy egyidejűségi szabálysértés miatt, értesítjük őket, és esetleg szerkesztési módban tartjuk a rácsot. Nézzük meg, hogyan lehet ezt elérni.

3. lépés: Annak meghatározása, hogy mikor történt egyidejűségi szabálysértés

Mivel egy egyidejűségi szabálysértés elutasítja az elvégzett módosításokat, érdemes figyelmeztetni a felhasználót, ha egyidejűségi szabálysértés történt. A felhasználó értesítéséhez vegyen fel egy címke webvezérlőt a ConcurrencyViolationMessage lap tetejére, amelynek Text tulajdonsága a következő üzenetet jeleníti meg: Egy másik felhasználó által egyidejűleg frissített rekordot próbált frissíteni vagy törölni. Tekintse át a másik felhasználó módosításait, majd végezze el újra a frissítést vagy a törlést. Állítsa a Címke vezérlőelem CssClass tulajdonságát a "Warning" értékre, amely egy CSS-osztály Styles.css, és a szöveget piros, dőlt, félkövér, nagy betűtípussal jeleníti meg. Végül állítsa be a Címkék Visible és EnableViewState tulajdonságait False értékre. Ez elrejti a címkét, kivéve azokat a postbackeket, ahol a tulajdonságát kifejezetten VisibleTrue-re állítjuk.

Címkevezérlő hozzáadása a laphoz a figyelmeztetés megjelenítéséhez

8. ábra: Címkevezérlő hozzáadása a laphoz a figyelmeztetés megjelenítéséhez (kattintson ide a teljes méretű kép megtekintéséhez)

Frissítés vagy törlés végrehajtásakor a GridView s RowUpdated és RowDeleted az eseménykezelők aktiválódik, miután az adatforrás-vezérlő végrehajtotta a kért frissítést vagy törlést. Meghatározhatjuk, hogy hány sort érintett a művelet ezekből az eseménykezelőkből. Ha a hiba nulla sort érintett, a címkét ConcurrencyViolationMessage szeretnénk megjeleníteni.

Hozzon létre egy eseménykezelőt mind a RowUpdated és RowDeleted eseményekhez, és adja hozzá a következő kódot:

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

Mindkét eseménykezelőben ellenőrizzük a e.AffectedRows tulajdonságot, és ha az értéke 0, akkor a ConcurrencyViolationMessage Címke tulajdonság Visibleértéke True legyen . RowUpdated Az eseménykezelőben arra is utasítjuk a GridView-t, hogy maradjon szerkesztési módban a KeepInEditMode tulajdonság igaz értékre állításával. Ennek során újra kell kötnünk az adatokat a rácshoz, hogy a többi felhasználó adatait betöltsük a szerkesztőfelületre. Ez a DataBind() metódus meghívásával érhető el a GridView-ben.

A 9. ábrán látható, hogy ezzel a két eseménykezelővel egy nagyon észrevehető üzenet jelenik meg, amikor egyidejűségi szabálysértés történik.

Egyidejűség megsértése esetén üzenet jelenik meg

9. ábra: Üzenet jelenik meg egyidejűségi szabálysértés esetén (kattintson ide a teljes méretű kép megtekintéséhez)

Összefoglalás

Amikor olyan webalkalmazást hoz létre, amelyben több egyidejű felhasználó szerkeszti ugyanazokat az adatokat, fontos megfontolni az egyidejűség-vezérlési beállításokat. Alapértelmezés szerint az ASP.NET adat webes vezérlői és adatforrás-vezérlői nem használnak egyidejűségi vezérlőt. Ahogy ebben az oktatóanyagban láttuk, az optimista egyidejűség-vezérlés megvalósítása az SqlDataSource-nal viszonylag gyors és egyszerű. Az SqlDataSource kezeli az automatikusan létrehozott WHERE és UPDATE utasításokhoz hozzáadott bővített DELETE záradékok legtöbb teendőjét, de az NULL értékoszlopok kezelésében van néhány apróság, amint azt az Értékek helyes kezelése NULL szakaszban tárgyaltuk.

Ez az oktatóanyag befejezi az SqlDataSource vizsgálatát. A fennmaradó oktatóanyagok az ObjectDataSource és a rétegzett architektúra használatával térnek vissza az adatokkal való munkához.

Boldog programozást!

Tudnivalók a szerzőről

Scott Mitchell, hét ASP/ASP.NET-könyv szerzője és a 4GuysFromRolla.com alapítója, 1998 óta dolgozik a Microsoft webtechnológiáival. Scott független tanácsadóként, edzőként és íróként dolgozik. Legújabb könyve Sams Teach Yourself ASP.NET 2.0 24 órában. Itt érhető el mitchell@4GuysFromRolla.com.