Skip to content

7. Beheer van gelijktijdige toegang tot gegevens

Tot nu toe hebben we tabellen gebruikt waarvan wij de enige gebruikers waren. In de praktijk worden gegevens op een machine met meerdere gebruikers meestal gedeeld tussen verschillende gebruikers. Dan rijst de vraag: wie mag welke tabel gebruiken en in welke vorm (raadplegen, invoegen, verwijderen, toevoegen, ...)?

7.1. Firebird-gebruikers aanmaken

Toen we met IB-Expert werkten, hebben we ons aangemeld als gebruiker SYSDBA. Deze informatie is te vinden in de eigenschappen van de geopende verbinding met SGBD:

Rechts zien we dat de aangemelde gebruiker [SYSDBA] is. Wat je niet ziet, is zijn wachtwoord [masterkey]. [SYSDBA] is een speciale gebruiker van Firebird: hij heeft alle rechten op alle objecten die worden beheerd door SGBD. Je kunt nieuwe gebruikers aanmaken met IBExpert via de optie [Tools / User Manager] of het volgende pictogram:

Image

We krijgen het venster voor gebruikersbeheer te zien:

Image

Met de knop [Add] kunt u nieuwe gebruikers aanmaken:

Image

Laten we dus de volgende gebruikers aanmaken:

naam
wachtwoord
ADMIN1
admin1
ADMIN2
admin2
SELECT1
select1
SELECT2
select2
UPDATE1
update1
UPDATE2
update2

7.2. Toegangsrechten toekennen aan gebruikers

Een database is eigendom van degene die deze heeft aangemaakt. De databases die we tot nu toe hebben aangemaakt, waren eigendom van de gebruiker [SYSDBA]. Om het begrip rechten te illustreren, maken we (Database / Create Database) een nieuwe database aan onder de gebruikersnaam [ADMIN1, admin1]:

Image

en sla deze op onder de alias DBACCES (ADMIN1). Door aliassen te gebruiken kun je verbindingen met dezelfde database openen met verschillende identificatiegegevens, waardoor je ze beter kunt terugvinden in de database-verkenner van IBExpert:

Laten we nu de volgende twee tabellen TA en TB aanmaken:

Tabel TA

Tabel TB

Deze tabellen staan los van elkaar.

Laten we met IB-Expert een tweede verbinding maken met de database [DBACCES], ditmaal onder de naam [ADMIN2 / admin2]. Hiervoor gebruiken we de optie [Database / Register Database]:

Laten we naar DBACCES (ADMIN2) gaan en een editor openen met de naam SQL (Shift + F12):

We zullen verschillende verbindingen kunnen gebruiken op dezelfde database [DBACCES]. Voor elk daarvan hebben we een editor SQL. In [1] geeft de editor SQL de alias van de verbonden database aan. Gebruik deze indicatie om te weten in welke editor SQL u zich bevindt. Dit is van belang omdat we verbindingen gaan aanmaken die niet dezelfde toegangsrechten hebben tot de objecten in de database.

Laten we de inhoud van de tabel TA opvragen:

Image

We krijgen de volgende foutmelding:

Image

Wat betekent dit? De database [DBACCESS] is aangemaakt door de gebruiker [ADMIN1] en is dus zijn eigendom. Alleen hij heeft toegang tot de verschillende objecten in deze database. Hij kan toegangsrechten toekennen aan andere gebruikers met het commando SQL GRANT. Dit commando kent verschillende syntaxisvormen. Een daarvan is de volgende:

syntaxe
GRANT privilege1, privilege2, ...| ALL PRIVILEGES
ON table/vue
TO gebruiker1, gebruiker2, ...| PUBLIC
[ WITH GRANT OPTION ]
action
verleent toegangsrechten privilègei of alle rechten (ALL PRIVILEGES) op de table of vue aan de gebruikers utilisateuri of aan alle gebruikers ( PUBLIC ). De clausule WITH GRANT OPTION stelt gebruikers die de rechten hebben ontvangen in staat om deze op hun beurt door te geven aan andere gebruikers.

Tot de rechten die kunnen worden toegekend behoren onder meer de volgende:

DELETE
het recht om de opdracht DELETE op de tabel of weergave te gebruiken.
INSERT
het recht om de opdracht INSERT op de tabel of weergave te gebruiken
SELECT
recht om de opdracht SELECT op de tabel of weergave te gebruiken
UPDATE
recht om de opdracht UPDATE op de tabel of weergave te gebruiken. Dit recht kan worden beperkt tot bepaalde kolommen met de volgende syntaxis: GRANT update (col1, col2, ...) ON tabel/weergave TO gebruiker1, gebruiker2, ...| PUBLIC [ WITH GRANT OPTION ]

Laten we gebruiker [ADMIN2] het recht SELECT toekennen op de tabel TA. Alleen de eigenaar van de tabel kan dit recht toekennen, c.a.d. Hier is dat [ADMIN1]. Laten we naar de verbinding DBACCES (ADMIN1) gaan en een nieuwe editor openen SQL (Shift+F12):

Image

Vervolgens schakelen we tussen de twee SQL-editors. Om het overzicht te behouden, kunnen we de optie [Windows] in het menu gebruiken:

Image

Hierboven zien we de twee editors SQL, die elk aan een specifieke gebruiker zijn gekoppeld. Laten we teruggaan naar de editor SQL (ADMIN1) en de volgende opdracht uitvoeren:

Image

Bevestig dit vervolgens met een COMMIT:

Image

Nu we dit hebben gedaan, gaan we naar de editor van gebruiker ADMIN2 om de opdracht SELECT, die was mislukt, opnieuw uit te voeren:

Image

We krijgen de volgende foutmelding:

Image

De gebruiker [ADMIN2] heeft nog steeds geen recht om de tabel [TA] te raadplegen. Het lijkt er namelijk op dat de rechten van een gebruiker worden geladen op het moment dat hij inlogt. [ADMIN2] zou dan nog steeds dezelfde rechten hebben als bij het begin van zijn sessie, namelijk geen. Laten we dit controleren. Laten we de gebruiker [ADMIN2] uitloggen:

  • ga naar zijn verbinding
  • vraag om afmelding door met de rechtermuisknop op de verbinding te klikken en de optie [Deconnect from database] te kiezen of (Shift + Ctrl + D)

Image

Als er in een venster om [COMMIT] wordt gevraagd, voer dan [COMMIT] in. Meld vervolgens de gebruiker [ADMIN2] opnieuw aan via de bovenstaande optie [Reconnect]. Als dit is gebeurd, gaan we terug naar de editor SQL (ADMIN2) en voeren we het verzoek SELECT dat is mislukt opnieuw uit:

Image

We krijgen dan het volgende resultaat:

Image

Deze keer kan ADMIN2 de tabel TA raadplegen dankzij het recht SELECT dat de eigenaar ADMIN1 hem heeft toegekend. Normaal gesproken is dit het enige recht dat hij heeft. Laten we dit controleren. Nog steeds in de editor SQL (ADMIN2):

Het scherm rechts laat zien dat ADMIN2 geen recht DELETE heeft op de tabel TA.

Laten we teruggaan naar de editor van SQL (ADMIN1) om de gebruiker ADMIN2 meer rechten te geven. We voeren achtereenvolgens de volgende twee commando’s uit:

  • het eerste commando geeft de gebruiker ADMIN2 alle toegangsrechten tot de tabel [TA], met bovendien de mogelijkheid om zelf ook rechten toe te kennen (WITH GRANT OPTION)
  • het tweede commando bevestigt het vorige

Zodra dit is gebeurd, vernieuwen we, net als eerder, de verbinding van de gebruiker [ADMIN2] (Afmelden / Opnieuw aanmelden) en voeren we vervolgens in de editor SQL (ADMIN2) de volgende commando's in:

ADMIN2 heeft alle rijen uit de tabel TA verwijderd. Laten we deze verwijdering ongedaan maken met een ROLLBACK:

Laten we controleren of ADMIN2 op zijn beurt rechten kan verlenen voor de tabel TA.

Laten we nu een verbinding openen met de database [DBACCES] (Database / Register database) onder de naam [SELECT1 / select1], een van de eerder aangemaakte gebruikers, en vervolgens dubbelklikken op de zo gecreëerde koppeling in [Database Explorer]:

Ga naar deze nieuwe verbinding en open een nieuwe SQL-editor (Shift + F12) om daar de volgende opdrachten in te voeren:

De gebruiker SELECT1 heeft inderdaad het recht SELECT op de tabel TA. Kan hij dit recht overdragen aan de gebruiker SELECT2?

 

De bewerking is mislukt omdat de gebruiker SELECT1 niet het recht heeft gekregen om het recht SELECT, dat hij van de gebruiker ADMIN2 heeft ontvangen, door te geven. Hiervoor had degebruiker ADMIN2 de clausule WITH GRANT OPTION in zijn opdracht SQL GRANT. De regels voor het doorgeven zijn eenvoudig:

  • een gebruiker mag alleen de rechten doorgeven die hij heeft ontvangen, en niet meer
  • hij kan ze alleen doorgeven als hij ze heeft ontvangen met het privilege [WITH GRANT OPTION]

Een toegekend recht kan worden ingetrokken met de opdracht REVOKE:

syntaxe
REVOKE privilege1, privilege2, ...| ALL PRIVILEGES
ON table/vue
FROM gebruiker1, gebruiker2, ...| PUBLIC
action
verwijdert toegangsrechten privilègei of alle rechten (ALL PRIVILEGES) op de table of vue voor de gebruikers utilisateuri of voor alle gebruikers ( PUBLIC ).

Laten we het eens proberen. Laten we teruggaan naar de editor van SQL van ADMIN2 om de bevoegdheid SELECT in te trekken die we aan de gebruiker SELECT1 hebben toegekend:

Laten we de verbinding van gebruiker SELECT1 verbreken en vervolgens opnieuw tot stand brengen. Vraag vervolgens in de editor SQL (SELECT1) de inhoud van de tabel TA op:

De gebruiker SELECT1 heeft inderdaad zijn leesrecht voor de tabel TA verloren. Opgemerkt moet worden dat het ADMIN2 was die hem dit recht had toegekend en dat het ADMIN2 was die het hem heeft ontnomen. Als ADMIN1 probeert het recht in te trekken, wordt er geen fout gemeld, maar vervolgens blijkt dat SELECT1 zijn recht SELECT heeft behouden.

Een recht kan aan iedereen worden toegekend met de syntaxis: GRANT recht(en) ON tabel / weergave TO PUBLIC. Laten we dus het recht SELECT op de tabel TA aan iedereen toekennen. Hiervoor kunnen we ADMIN1 of ADMIN2 gebruiken. We gebruiken ADMIN2:

Laten we een verbinding maken met de database met de gebruiker USER1 / user1:

Met de verbinding DBACCES (USER1) openen we een nieuwe editor SQL (Shift + F12) en voeren we de volgende opdrachten in:

De gebruiker USER1 heeft inderdaad de bevoegdheid SELECT voor de tabel TA.

7.3. De transacties

7.3.1. Beveiligingsniveaus

We laten nu het probleem van de toegangsrechten tot databaseobjecten even achter ons om het probleem van gelijktijdige toegang tot deze objecten te bespreken. Twee gebruikers met voldoende toegangsrechten tot een object in de database, bijvoorbeeld een tabel, willen dit tegelijkertijd gebruiken. Wat gebeurt er dan?

Elke gebruiker werkt binnen een transactie. Een transactie is een reeks opdrachten SQL die op een "atomaire" manier wordt uitgevoerd:

  • ofwel slagen alle bewerkingen
  • ofwel mislukt er één, en dan worden alle voorgaande bewerkingen ongedaan gemaakt

Uiteindelijk zijn de bewerkingen van een transactie ofwel allemaal met succes doorgevoerd, ofwel is er geen enkele doorgevoerd. Wanneer de gebruiker zelf de controle heeft over de transactie (wat in dit hele document het geval is), bevestigt hij een transactie met een opdracht COMMIT of annuleert hij deze met een opdracht ROLLBACK.

Elke gebruiker werkt in een transactie die hem toebehoort. Gewoonlijk worden vier niveaus van isolatie tussen de verschillende gebruikers onderscheiden:

  • Uncommitted Read
  • Committed Read
  • Repeatable Read
  • Serializable

Uncommitted Read

Deze isolatiemodus wordt ook wel "Dirty Read" genoemd. Hier volgt een voorbeeld van wat er in deze modus kan gebeuren:

  1. een gebruiker U1 start een transactie op een tabel T
  2. een gebruiker U2 start een transactie op dezelfde tabel T
  3. gebruiker U1 wijzigt rijen in tabel T, maar bevestigt deze nog niet
  4. de gebruiker U2 „ziet“ deze wijzigingen en neemt beslissingen op basis van wat hij ziet
  5. de gebruiker rolt zijn transactie terug met een ROLLBACK

We zien dat in stap 4 de gebruiker U2 een beslissing heeft genomen op basis van gegevens die later onjuist zullen blijken te zijn.

Committed Read

Deze isolatiemodus voorkomt het eerder genoemde probleem. In deze modus zal gebruiker U2 in stap 4 de wijzigingen die gebruiker U1 in tabel T heeft aangebracht, niet „zien”. Hij zal deze pas zien nadat U1 zijn transactie heeft vastgelegd (COMMIT).

In deze modus, ook wel "Unrepeatable Read" genoemd, kunnen de volgende situaties zich voordoen:

  1. een gebruiker U1 start een transactie op een tabel T
  2. een gebruiker U2 start een transactie op dezelfde tabel T
  3. de gebruiker U2 voert een SELECT uit om het gemiddelde te berekenen van kolom C van de rijen in T die aan een bepaalde voorwaarde voldoen
  4. de gebruiker U1 wijzigt (UPDATE) bepaalde waarden in kolom C van T en valideert deze (COMMIT)
  5. de gebruiker U2 voert opnieuw dezelfde SELECT uit als in 3. Hij zal ontdekken dat het gemiddelde van kolom C is veranderd als gevolg van de wijzigingen die door U1 zijn aangebracht.

Nu ziet gebruiker U2 alleen de wijzigingen die door U1 zijn „gevalideerd”. Maar terwijl hij in dezelfde transactie blijft, leveren twee identieke bewerkingen (3 en 5) verschillende resultaten op. De term "Unrepeatable Read" verwijst naar deze situatie. Dit is vervelend voor iemand die een stabiel beeld van tabel T wil hebben.

Repeatable Read

In deze isolatiemodus is een gebruiker verzekerd van dezelfde resultaten bij het uitlezen van de database, zolang hij binnen dezelfde transactie blijft. Hij werkt met een momentopname waarin wijzigingen die door andere transacties zijn aangebracht – zelfs als deze zijn gevalideerd – nooit worden doorgevoerd. Hij zal deze wijzigingen pas zien wanneer hij zelf zijn transactie afsluit met een COMMIT of ROLLBACK.

Deze isolatiemodus is echter nog niet perfect. Na bewerking 3 hierboven worden de rijen die door gebruiker U2 zijn geraadpleegd, vergrendeld. Tijdens bewerking 4 kan gebruiker U1 de waarden in kolom C van deze rijen niet wijzigen (UPDATE). Hij kan echter wel rijen toevoegen (INSERT). Als sommige van de toegevoegde rijen voldoen aan de in stap 3 geteste voorwaarde, zal bewerking 5 een ander gemiddelde opleveren dan dat in stap 3, vanwege de toegevoegde rijen.

Om dit nieuwe probleem op te lossen, moet worden overgeschakeld naar de isolatiemodus „Serializable“.

Serializable

In deze isolatiemodus zijn transacties volledig afgeschermd van elkaar. Dit zorgt ervoor dat het resultaat van twee gelijktijdig uitgevoerde transacties hetzelfde is als wanneer ze na elkaar zouden worden uitgevoerd. Om dit te bereiken, wordt de gebruiker U1 tijdens bewerking 4 – waarin hij regels wil toevoegen die het resultaat van de transactie SELECT van gebruiker U1 zouden wijzigen – hierin verhinderd. Een foutmelding zal aangeven dat het invoegen niet mogelijk is. Dit wordt pas mogelijk wanneer gebruiker U2 zijn transactie heeft bevestigd.

De vier isolatieniveaus voor transacties zijn niet in alle gevallen beschikbaar. Firebird biedt de volgende isolatieniveaus:

  • snapshot: standaard isolatiemodus. Komt overeen met de modus „Repeatable Read“ van de standaard SQL.
  • committed read: komt overeen met de modus "committed read" van de standaard SQL

Dit isolatieniveau wordt ingesteld met het commando SET TRANSACTION:

syntaxe
SET TRANSACTION
[READ WRITE | READ ONLY]
[WAIT|NOWAIT]
ISOLATION LEVEL [SNAPSHOT | READ COMMITTED]
fonctionnement
de onderstreepte trefwoorden zijn de standaardwaarden
READ WRITE: de transactie kan lezen en schrijven
READ ONLY: de transactie kan alleen lezen
WAIT: bij een conflict tussen twee transacties wacht de transactie die haar bewerking niet heeft kunnen uitvoeren totdat de andere transactie is gevalideerd. Ze kan geen opdrachten meer versturen (SQL).
NOWAIT: de transactie die haar bewerking niet heeft kunnen uitvoeren, wordt niet geblokkeerd. Ze ontvangt een foutmelding en kan doorgaan met werken.
ISOLATION LEVEL [SNAPSHOT | READ COMMITTED]: isolatieniveau

Laten we het eens proberen. In de editor SQL (ADMIN1) voeren we de volgende opdracht SQL in:

Image

We zien dat deze niet is toegestaan. We weten niet waarom...

Met IB-Expert kun je de isolatiemodus op een andere manier instellen. Klik met de rechtermuisknop op de verbinding DBACCES(ADMIN1) om de optie [Database Registration Info] te selecteren:

Het scherm rechts toont dat er een optie [Transactions] beschikbaar is. Hiermee kunnen we het isolatieniveau van de transacties instellen. We stellen dit hier in op [snapshot]. We doen hetzelfde met de verbinding DBACCES (ADMIN2).

7.3.2. De snapshot-modus

Laten we eens kijken naar het isolatieniveau snapshot, de standaard isolatiemodus van Firebird. Wanneer de gebruiker een transactie start, wordt er een momentopname van de database gemaakt. De gebruiker gaat vervolgens aan de slag met deze momentopname. Elke gebruiker werkt dus aan een eigen momentopname van de database. Als hij hierin wijzigingen aanbrengt, zien de andere gebruikers deze niet. Zij zullen deze pas zien wanneer de gebruiker die de wijzigingen heeft aangebracht, deze heeft vastgelegd met een COMMIT.

Er zijn twee gevallen mogelijk:

  • een gebruiker leest de tabel (select) terwijl een andere gebruiker deze aan het wijzigen is (insert, update, delete)
  • beide gebruikers willen de tabel tegelijkertijd wijzigen

7.3.2.1. Het principe van consistent lezen

Stel dat twee gebruikers, U1 en U2, aan dezelfde tabel TAB werken:

      --------+----------+--------+-------+----------------------
              T1a       T2a      T1b     T2b 

De transactie van gebruiker U1 begint op tijdstip T1a en eindigt op tijdstip T1b.

De transactie van gebruiker U2 begint op tijdstip T2a en eindigt op tijdstip T2b.

U1 bewerkt een foto van TAB die is genomen op het tijdstip T1a. Tussen T1a en T1b wijzigt hij TAB. Andere gebruikers krijgen pas toegang tot deze wijzigingen op tijdstip T1b, wanneer U1 een COMMIT uitvoert.

U2 werkt aan een foto van TAB die is genomen op het moment T2a, dus dezelfde foto als die door U1 wordt gebruikt (als andere gebruikers het origineel ondertussen niet hebben gewijzigd). Hij „ziet” de wijzigingen die gebruiker U1 mogelijk heeft aangebracht in TAB niet. Hij zal deze pas kunnen zien op het tijdstip T1b.

Laten we dit illustreren aan de hand van onze database [DBACCES]. We laten de twee gebruikers [ADMIN1] en [ADMIN2] tegelijkertijd werken. Laten we naar de verbinding DBACCES (ADMIN1) gaan en in de editor SQL van ADMIN1 de volgende handelingen uitvoeren:

ADMIN1 heeft rij nr. 2 van de tabel TA gewijzigd, maar heeft zijn bewerking (COMMIT) nog niet bevestigd. De gebruiker ADMIN2 voert vervolgens een SELECT uit op de tabel TA (we gaan over naar de editor SQL van ADMIN2). We bevinden ons vóór tijdstip T2a uit het voorbeeld.

Terug naar de editor SQL van ADMIN1, die de toevoeging valideert:

 

Terug naar de editor SQL van ADMIN2 om SELECT opnieuw te maken:

ADMIN2 ziet de wijzigingen die zijn aangebracht door ADMIN1. In de snapshot-modus ziet een transactie de wijzigingen die door andere transacties zijn aangebracht pas als deze laatste zijn voltooid.

7.3.2.2. Gelijktijdige wijziging van hetzelfde databaseobject door twee transacties

Laten we een voorbeeld uit de boekhouding nemen: U1 en U2 werken aan rekeningen. U1 debiteert comptex met een bedrag S en crediteert comptey met hetzelfde bedrag. Dit gebeurt in verschillende stappen:

      --------+----------+--------+-------+----------------------
              T1a       T1b     T1c      T1d 

U1 start een transactie op tijdstip T1a, debiteert comptex op tijdstip T1b, crediteert comptey op tijdstip T1c en valideert beide transacties op tijdstip T1d. Stel verder dat U2 hetzelfde wil doen, zijn transactie begint op tijdstip T2a en deze beëindigt op tijdstip T2d volgens het volgende schema:

      --------+----------+----+----+-------+------+-----+-------+---------
              T1a       T1b  T2a   T1c     T2b   T1d   T2c    T2d

Op tijdstip T2 wordt een momentopname van de rekeningentabel gemaakt voor U2. Deze is consistent volgens het principe van snapshot. U2 ziet de beginstand van de rekeningen comptex en comptey, omdat U1 zijn transacties nog niet heeft gevalideerd.

Stel dat comptex een beginsaldo van 1000 € heeft en dat zowel de gebruiker U1 als de gebruiker U2 100 € van deze rekening willen afschrijven.

  • Op tijdstip T1b vermindert U1 het saldo van comptex met 100 € en brengt het daarmee op 90 €. Deze transactie wordt pas op tijdstip T1d gevalideerd.
  • Op tijdstip T2b ziet U2 dat comptex 1000 € heeft (principe van coherente lezing) en vermindert het saldo met 100 €, waardoor het op 90 € komt.
  • Uiteindelijk, op tijdstip T2d, wanneer alles is gevalideerd, zal comptex een saldo van 90 € hebben in plaats van de verwachte 80 €.

De oplossing voor dit probleem is te voorkomen dat U2 comptex wijzigt zolang U1 zijn transactie niet heeft voltooid. U2 wordt dus geblokkeerd tot het tijdstip T1d. De modus snapshot biedt dit mechanisme.

Laten we dit illustreren aan de hand van de database DBACCES. ADMIN1 start een transactie in zijn editor SQL (ADMIN1):

We zijn begonnen met het uitvoeren van een COMMIT om er zeker van te zijn dat we een nieuwe transactie starten. Vervolgens hebben we regel nr. 4 verwijderd. De transactie is nog niet gevalideerd.

ADMIN2 start op zijn beurt een transactie in zijn editor SQL (ADMIN2):

Het scherm rechts laat zien dat ADMIN2 regel nr. 4 wilde wijzigen. Er werd hem meegedeeld dat dit niet mogelijk was omdat iemand anders deze regel al had gewijzigd, maar deze wijziging nog niet had gevalideerd.

Laten we teruggaan naar de editor SQL (ADMIN1) om de COMMIT te maken:

Image

Laten we teruggaan naar de editor SQL(ADMIN2) om de opdracht UPDATE opnieuw uit te voeren:

De bewerking UPDATE verloopt goed, ook al bestaat regel nr. 4 niet meer, zoals blijkt uit de daaropvolgende SELECT. Op dat moment ontdekt ADMIN2 dat de regel niet meer bestaat.

7.3.2.3. De modus „Repeatable Read“

Laten we nu de modus „Repeatable Read“ illustreren. Dit isolatieniveau wordt geboden door de „snapshot“-modus. Deze zorgt ervoor dat een transactie altijd hetzelfde resultaat krijgt bij het lezen van de database.

Laten we beginnen met de bewerking van de editor SQL van ADMIN2:

Laten we nu verdergaan met de editor SQL van ADMIN1:

 

De gebruiker ADMIN1 heeft twee regels toegevoegd en zijn transactie bevestigd. Laten we nu teruggaan naar de editor SQL (ADMIN2) om de SELECT SUM opnieuw uit te voeren:

We zien dat ADMIN2 de toegevoegde regels van ADMIN1 niet herkent, hoewel deze zijn gevalideerd door een COMMIT. De SELECT SUM levert hetzelfde resultaat op als vóór de toevoegingen. Dit is het principe van de ‘Repeatable Read’.

Laten we nu, nog steeds in de editor SQL (ADMIN2), valideren we de transactie met een COMMIT en voeren we vervolgens de SELECT SUM opnieuw uit:

De regels die door ADMIN1 zijn toegevoegd, worden nu meegenomen.

7.3.3. De modus „Committed Read“

Laten we nu de modus "Committed Read" illustreren. Dit isolatieniveau is vergelijkbaar met dat van snapshot, behalve wat betreft "Repeatable Read".

We beginnen met het wijzigen van het transactie-isolatieniveau van beide verbindingen.

  • we verbreken de verbinding van de twee gebruikers ADMIN1 en ADMIN2
  • we wijzigen het isolatieniveau van hun transacties

Image

  • we maken opnieuw verbinding met de gebruikers ADMIN1 en ADMIN2

We pakken nu het vorige voorbeeld weer op, waarin ‘Repeatable Read’ werd geïllustreerd, om te laten zien dat we niet langer hetzelfde gedrag zien. Laten we beginnen met de editor SQL van ADMIN2:

Laten we nu verdergaan met de editor SQL van ADMIN1:

 

De gebruiker ADMIN1 heeft twee regels toegevoegd en zijn transactie bevestigd. Laten we nu teruggaan naar de editor SQL (ADMIN2) om de SELECT SUM opnieuw uit te voeren:

De SELECT SUM levert niet hetzelfde resultaat op als vóór de toevoegingen die door ADMIN1 zijn aangebracht. Dit is het verschil tussen de modi ‘snapshot’ en ‘read committed’.