Quickstart project: examples/concurrency
in de cursus repository (download repo zip). Het bevat een JDBC implementatie van de gekende studenten opgave, inclusief een Runnable
thread worker die INSERT
, UPDATE
of DELETE
statements issuen naar de database. Het probleem wat we hier proberen te simuleren is DIRTY READS.
SELECT
teruggegeven?setAutoCommit()
in de ConnectionManager
. Zie je een verschil?setTransactionIsolation()
op de connection. Merk op dat SQLite enkel SERIALIZABLE
en READ_UNCOMMITED
ondersteund, maar het onmogelijk is om dirty reads te simuleren. Zie ook https://github.com/changemyminds/Transaction-Isolation-Level-Issue en de Oracle docs voor het verschil tussen bijvoorbeeld READ_UNCOMMITTED
en READ_COMMITTED
? Kan je uit de context opmaken wat een “dirty read” is?for {}
loop tientallen verschillende threads aan en laat ze verschillende acties op de DB uitvoeren (lezen, schrijven, updaten, …). Loopt er iets mis? Wat kan je programmatorisch doen om de chaos tot het minimum te beperken?Om concurrency problemen makkelijk te kunnen demonstreren gebruiken we géén SQLite vanwege SQLite’s shared cache mode. Let dus op je SQL syntax en connection string. Kleine verschillen kunnen SQL Exceptions veroorzaken bij andere database implementaties.
Uit de code blijkt dat alle threads momenteel éénzelfde connection instance delen via de StudentRepository
implementatie. In de praktijk wordt er voor client/server applicaties altijd connection pooling toegepast: een aantal connections zijn beschikbaar in een pool, waar de clients uit kunnen kiezen. Als er een beschikbaar is, kan deze verder gaan. Als dat niet zo is, moet die bepaalde request wachten, tot een andere klaar is met zijn database acties en de connection terug vrijgeeft, opnieuw in de pool. Op die manier kan je bijvoorbeeld 6 connections verdelen over 10+ client threads, zoals in deze figuur (bron: oracle docs):
Voor embedded single-file databases als SQLite is dit niet de gewoonte. Hibernate (zie 3. Database APIs) voorziet verschillende properties om connection pooling in te stellen, zoals aantal connections, aantal threads die kunnen requesten, timeout request, enzovoort. We gaan hier verder niet op in.