Tijdens een transactie worden de gegevens in een databank vergrendeld zodat andere gebruikers / apps er tijdelijk geen wijzigingen aan kunnen brengen. Pa als de transactie is afgesloten (commit of rollback) wordt de vergrendeling opgeheven.
Dit is dus een voorbeeld van Pessimistic Locking, waarbij we er vanuit gaan dat er iets fout kan gebeuren en dat willen we voorkomen. Dit t.o.v. Optimistic Locking, waarbij we zeggen date wel goed zal gaan, en als het fout gaat lossen we het probleem wel op als het zich stelt.
Gegevens lezen uit de databank is bij zo een locking wel mogelijk. Hierbij zijn er verschillende scenario’s die zich kunnen voordoen.
Dirty Read. De huidige transactie leest gegevens die nog niet gecommit zijn door een andere transactie
Non-repeatable read. Als een transactie gegevens opnieuw leest, maar deze blijken al veranderd te zijn in de effectieve databank. Dit door een andere transactie die zijn wijzigingen gecommit heeft.
Phantom read. Als een query opnieuw wordt uitgevoerd maar de gegevens blijken achterliggend veranderd te zijn door een andere transactie die zijn wijzigingen heeft gecommit.
Deze mogelijkheden worden bepaald door de Transaction Isolation Level. De stand hiervan kan worden opgevraagd met de methoden getTransactionIsolation() en setTransactionIsolaction() van de interface Connection.
Als argument kunnen we dan verschillende constanten opgeven uit de Connection Interface die een bepaald gedrag gaan toestaan of niet. We geven het hieronder kort even terug. Links hebben we het Level (constante), rechts de verschillende lees gedragingen die mogelijk zijn. Indien er een X staat is de optie mogelijk, bij een O is de optie niet mogelijk.
Level | Dirty Read | Non-repeatable Read | Phantom Read |
TRANSACTION_NONE | Geen Transactie | ||
TRANSACTION_READ_UNCOMMITTED | X | X | X |
TRANSACTION_READ_COMMITTED | O | X | X |
TRANSACTION_REPEATABLE_READ | O | O | X |
TRANSACTION_SERIALIZABLE | O | O | O |
Hoe hoger het isolatie niveau dus is. Hoe beter de gegevens consistentie is maar ook een beperktere simultane gegevenstoegang we krijgen. Hierdoor zal de globale performantie lager liggen.
Desondanks zijn deze systemen heel belangrijk. Denk aan het voorbeeld van de betalingen bij transacties. Je wilt niet dat geld dubbeel afgerekend wordt, of dat verschillende transactie met andere rekening-standen werken van jouw betaalrekening. ZO kan er geld verschijnen, maar dus ook geld verdwijnen.
Bij dit soort transacties spreken we van een atomair / gesynchroniseerd gebeuren. Hiervoor wordt het toegangsniveau Serializable gebruikt. Hierbij wordt dus een versie nummering bijgehouden.
Hier komen we later nog op terug.