Transactions, CAP and Scaling


In the last scriptum (Information_System_Architectures) we saw that every architecture is a trade-off between consistency, scalability and latency. This scriptum answers three questions:

  1. How does a database keep data correct? → transaction models (ACID vs. BASE)
  2. What happens when many users work at the same time? → isolation levels
  3. What happens when the database is spread over many machines? → CAP theorem and scaling

1. What is a transaction?

A transaction is a group of operations that belongs together. Either all of them happen, or none of them.


Classic example — a bank transfer of 100 € from Anna to Ben:

START TRANSACTION;
UPDATE account SET balance = balance - 100 
WHERE owner = 'Anna';
UPDATE account SET balance = balance + 100 
WHERE owner = 'Ben';
COMMIT;      -- or ROLLBACK; if something went wrong

If the server crashes after the first UPDATE, the money must not simply vanish.


2. ACID — the strict model

Used by classic relational databases (MySQL/InnoDB, PostgreSQL, SQL Server, SQLite).

LetterPropertyIn one sentenceBank example
AAtomicityAll or nothing.Never only one of the two UPDATEs.
CConsistencyA transaction moves the DB from one valid state to another valid state.Constraints hold, e.g. balance >= 0.
IIsolationParallel transactions do not disturb each other.A report never sees “money in flight”.
DDurabilityAfter COMMIT the data survives crashes.Power failure → transfer is still there.

Careful: The “C” in ACID (valid state, constraints) is not the same as the “C” in CAP (all nodes show the same data). Same letter, different meaning.


3. BASE — the relaxed model

Used by many distributed NoSQL systems (Cassandra, DynamoDB, CouchDB, …) where ACID across many nodes would be too slow.

LetterMeaningIn plain words
BABasically AvailableThe system always answers — maybe with slightly old data.
SSoft stateThe state can change even without new writes (copies sync in the background).
EEventual consistencyIf no new writes come in, all copies will eventually be equal.

Real-life analogy: a “like” counter on social media. If you see 1,203 likes and your friend sees 1,205 for a few seconds — nobody cares. A bank balance is different.


3.1 ACID vs. BASE at a glance

ACIDBASE
Prioritycorrectnessavailability & speed
Consistencystrong (immediately)eventual (after a while)
Scalingmostly verticalhorizontal, very good
Typical systemsMySQL, PostgreSQL, SQL ServerCassandra, DynamoDB, CouchDB
Typical usebanking, orders, stock levelssocial feeds, shopping carts, logs, IoT sensor data

It is not black and white: MongoDB has supported multi-document ACID transactions since version 4.0, and many NoSQL systems let you choose the consistency level per query.


4. Isolation levels

Perfect isolation (every transaction behaves as if it were alone) is expensive — it needs many locks and makes users wait. So the SQL standard defines four levels: the lower the level, the faster, but the more errors (anomalies) can happen.


4.1 The anomalies


Dirty Read — you read data that another transaction has not committed yet.

T1: UPDATE price = 50          (not committed)
T2: SELECT price  → 50         ← reads "dirty" data
T1: ROLLBACK                   → price was never really 50

Non-Repeatable Read — you read the same row twice and get different values.

T1: SELECT price → 40
T2: UPDATE price = 50; COMMIT
T1: SELECT price → 50       ← same query, different result

Phantom Read — you run the same query twice and new rows appear (or disappear).

T1: SELECT COUNT(*) FROM orders WHERE day = today → 10
T2: INSERT INTO orders ...; COMMIT
T1: SELECT COUNT(*) ...       → 11   ← a "phantom" row

4.2 The four levels

Isolation levelDirty ReadNon-Repeatable ReadPhantom ReadSpeed
Read Uncommittedpossiblepossiblepossiblefastest
Read Committed✗possiblepossible
Repeatable Read✗✗possible
Serializable✗✗✗slowest

Memory trick: every level going down removes one more anomaly.

Defaults:

  • MySQL (InnoDB): Repeatable Read
  • PostgreSQL, SQL Server, Oracle: Read Committed

4.3 How to set it

MySQL:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
START TRANSACTION;
  -- ...
COMMIT;

C# / ADO.NET:

using var tx = connection.BeginTransaction(
  IsolationLevel.Serializable);
// ... commands with tx ...
tx.Commit();

4.4 Bonus: the Lost Update

Two users read the stock (10), both subtract 1 and write back 9. Correct would be 8. One update is lost.


Solutions:

  • Let the DB calculate: UPDATE item SET stock = stock - 1 WHERE id = 7;
  • Pessimistic locking: SELECT ... FOR UPDATE locks the row until commit.
  • Optimistic locking: store a version number and update only WHERE version = @oldVersion (Entity Framework: concurrency token).

5. The CAP theorem

As soon as data is stored on several nodes, the network between them can fail. The CAP theorem says what you can still guarantee then.


LetterPropertyMeaning
CConsistencyEvery read returns the latest write — all nodes show the same data.
AAvailabilityEvery request gets an answer (no error, no timeout).
PPartition toleranceThe system keeps working although the network between nodes is broken.

CAP theorem: When a network partition happens, a distributed system must choose between Consistency and Availability.


5.1 Why you cannot have all three

    Node A  ───── X ─────  Node B        (network cable cut)
   price=50               price=40       (B has not received the update)

A user asks Node B for the price. Node B has two options:

  1) answer "40"          → available, but NOT consistent  (AP)
  2) refuse / wait        → consistent, but NOT available  (CP)

There is no third option. And because networks always fail sometimes, P is not optional in a real distributed system — the real choice is C or A.


6. CAP classification

ClassGives upBehaviour during a partitionExamples
CPAvailabilityRather return an error than wrong data.MongoDB (default: writes to the primary), HBase, etcd, ZooKeeper
APConsistencyAlways answer, sync later (eventual consistency).Cassandra, DynamoDB, CouchDB, DNS
CAPartition toleranceOnly possible if there is no network between nodes.a single MySQL / PostgreSQL server

               C
              / \
        CP   /   \   CA  (only single-node
            /     \       systems)
           P ----- A
              AP

How to choose:

  • Money, stock, reservations, anything where “wrong” is worse than “not now” → CP
  • Feeds, likes, carts, sensor data, where “now” is more important than “exact” → AP

Many modern databases are tunable: in Cassandra you can request QUORUM per query, in MongoDB you can read from secondaries. So “MongoDB is CP” describes the default, not a law of nature.


7. Scaling dimensions

7.1 Up or out?

DirectionWhat you do+ / –
Vertical (scale up)bigger machine: more CPU, RAM, SSD+ simple, ACID stays easy · – hard limit, expensive, single point of failure
Horizontal (scale out)more machines+ nearly unlimited, fault tolerant · – distribution → CAP problems

7.2 The Scale Cube (three axes of horizontal scaling)

              Y: split by function
              (microservices)
                 ▲
                 │
                 │
                 └────────► X: clone the same thing
                /           (replicas behind a load balancer)
               /
              ▼
     Z: split by data
     (sharding)

AxisIdeaExampleScales
Xidentical copies5 Web-API instances behind a load balancer; DB read replicasreads, requests
Ysplit by functionseparate services for users, orders, payments, each with its own DBteam size, features
Zsplit by datacustomers A–M on shard 1, N–Z on shard 2 (MongoDB sharded cluster)writes, data volume

7.3 Scaling and transactions — the connection

  • Vertical / single server: ACID is easy, everything is local.
  • X-axis replicas: reads scale; with async replication replicas can be stale → eventual consistency.
  • Y- and Z-axis: a transaction may touch several databases → needs 2-Phase-Commit (slow, blocking) or you accept BASE.

The more you scale out, the more you move from ACID towards BASE and from CA towards a conscious CP or AP decision.


8. Summary

  • ACID = strict and correct, BASE = available and scalable, eventually correct.
  • Isolation levels trade speed for protection against Dirty, Non-Repeatable and Phantom Reads. Serializable is safest, Read Uncommitted is fastest.
  • CAP: in a network partition you must choose C or A. P is not optional.
  • CP for money, AP for likes. CA only exists on a single node.
  • Scale up first (simple), scale out when you must: X = clone, Y = split functions, Z = split data.

9. Self-check questions

  1. Explain the four ACID properties using an online shop order.
  2. What is the difference between the “C” in ACID and the “C” in CAP?
  3. What does “eventual consistency” mean? Give an example where it is acceptable and one where it is not.
  4. Which anomaly is described here: “I counted 10 orders, ran the same query again and got 11.”?
  5. Which isolation level prevents dirty reads but still allows non-repeatable reads?
  6. What is the default isolation level of MySQL InnoDB?
  7. Two clerks sell the last ticket at the same time. Name the problem and two solutions.
  8. Why is “CA” not a real option for a distributed database?
  9. Classify a ticket booking system and a sensor-data logging system as CP or AP. Justify.
  10. Name the three axes of the Scale Cube with one example each.
  11. Why does sharding make transactions harder?

Short answers

  1. A: order row and stock reduction both happen or neither. C: stock never negative. I: another customer doesn’t see the half-finished order. D: after “order confirmed” the order survives a crash.
  2. ACID-C = rules/constraints are respected. CAP-C = all nodes return the latest value.
  3. Copies become equal after some time without new writes. OK: like counter. Not OK: account balance.
  4. Phantom read.
  5. Read Committed.
  6. Repeatable Read.
  7. Lost update (or double booking). Solutions: SELECT ... FOR UPDATE, optimistic locking with a version column, or an atomic UPDATE ... SET stock = stock - 1 WHERE stock > 0.
  8. Networks between nodes always fail sometimes, so the system must tolerate partitions. CA only works without a network — i.e. on one node.
  9. Ticket booking → CP (selling a seat twice is worse than a short error). Sensor logging → AP (losing availability means losing data; a few seconds of inconsistency don’t matter).
  10. X: replicas behind a load balancer. Y: microservices (orders, users, payments). Z: sharding by customer.
  11. A transaction may need rows on several shards → distributed transaction (2PC) which is slow and blocking, or you give up ACID.