Skip to content

In this project we have a look at two isolation levels: read committed and repeatable read. We will demonstrate their guarantees using different types of locks on these anomalies: nonrepeatable read, lost updates, and write skew.

Notifications You must be signed in to change notification settings

bkaminnski/isolation-levels

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Isolation levels demo

This project implements couple of examples from Designing Data-Intensive Applications by Martin Kleppmann, chapter 7, Transactions. Each scenario is presented in two isolation levels: read committed and repeatable read running against PostgreSQL database. Couple of locking modes are also used throughout examples, starting with no locks and (almost) plain entities, through implicit optimistic locks achieved by @Version annotation in JPA entities, to explicit locking on EntityManager with LockModeType: OPTIMISTIC and OPTIMISTIC_FORCE_INCREMENT. Each scenario uses a particular combination of isolation level and locking mode in step-by-step execution of two transactions running concurrently. In order to guarantee deterministic and repeatable behaviour, transactions flow is explicitely controlled by CountDownLatches. Each scenario is presented as a separate integration test running in Spring context.

Page 237 - Repeatable Read

  • RepeatableReadScenarioTest
    • read committed, no optimistic lock - should demonstrate nonrepeatable read anomaly
    • read committed, optimistic lock - should prevent nonrepeatable read anomaly by throwing optimistic lock exception
    • repeatable read, no optimistic lock - should prevent nonrepeatable read anomaly by reading both balances from before transaction
    • repeatable read, optimistic lock - should prevent nonrepeatable read anomaly by reading both balances from before transaction ignoring optimistic lock

Page 245 - Lost Updates

Scenario 1: A reads, B reads, A updates and commits, B updates and commits

  • CompareAndSetScenario1NonVersionedNoCompareTest

    • scenario 1, non versioned, no compare, read committed - update was lost - no mechanism could have prevented it
    • scenario 1, non versioned, no compare, repeatable read - lost update was prevented due to failure to acquire lock in database
  • CompareAndSetScenario1NonVersionedCompareOnContentTest

    • scenario 1, non versioned, compare on content, read committed - lost update was prevented due to compare after A committed
    • scenario 1, non versioned, compare on content, repeatable read - lost update was prevented due to failure to acquire lock in database
  • CompareAndSetScenario1VersionedTest

    • scenario 1, versioned, read committed - lost update was prevented due to optimistic lock
    • scenario 1, versioned, repeatable read - lost update was prevented due to failure to acquire lock in database

Scenario 2: A reads, B reads, A updates, B updates, A commits, B commits

  • CompareAndSetScenario2NonVersionedNoCompareTest

    • scenario 2, non versioned, no compare, read committed - update was lost - and B kindly waited until A committed preventing dirty write
    • scenario 2, non versioned, no compare, repeatable read - lost update was prevented due to failure to acquire lock in database - and B kindly waited until A committed preventing dirty write
  • CompareAndSetScenario2NonVersionedCompareOnContentTest

    • scenario 2, non versioned, compare on content, read committed - update was lost because B compared before A committed making comparison useless - and B kindly waited until A committed preventing dirty write
    • scenario 2, non versioned, compare on content, repeatable read - lost update was prevented due to failure to acquire lock in database - and B kindly waited until A committed preventing dirty write
  • CompareAndSetScenario2VersionedTest

    • scenario 2, versioned, read committed - lost update was prevented due to optimistic lock - and B kindly waited until A committed preventing dirty write
    • scenario 2, versioned, repeatable read - lost update was prevented due to failure to acquire lock in database - and B kindly waited until A committed preventing dirty write

Page 247 - Write Skew

  • WriteSkewScenarioNonVersionedTest

    • write skew scenario, non versioned, read committed - invariant violated
    • write skew scenario, non versioned, repeatable read - invariant violated
  • WriteSkewScenarioVersionedNoExplicitLockTest

    • write skew scenario, versioned, no explicit lock, read committed - invariant violated
    • write skew scenario, versioned, no explicit lock, repeatable read - invariant violated
  • WriteSkewScenarioVersionedOptimisticLockTest

    • write skew scenario, versioned, optimistic lock, read committed - invariant violated
    • write skew scenario, versioned, optimistic lock, repeatable read - invariant violated
  • WriteSkewScenarioVersionedOptimisticLockForceIncrementTest

    • write skew scenario, versioned, optimistic lock force increment, read committed - invariant preserved due to explicit optimistic lock
    • write skew scenario, versioned, optimistic lock force increment, repeatable read - invariant preserved due to failure to acquire lock in database - optimistic lock being only excuse for update

About

In this project we have a look at two isolation levels: read committed and repeatable read. We will demonstrate their guarantees using different types of locks on these anomalies: nonrepeatable read, lost updates, and write skew.

Topics

Resources

Stars

Watchers

Forks