BASE Theorem Explained: How it Stands Against ACID
Why Your Bank and Twitter Run on Different Consistency Rules
When you transfer $100, you need a guarantee: the money leaves your account and lands in the recipient's account as one atomic operation.
π― System Scenario & Requirements
System Goal
When you transfer $100, you need a guarantee: the money leaves your account and lands in the recipient's account as one atomic operation.
Actors & Components
- Client Layer
- Ingress & Edge
- Core Processing
- Data & Persistence
- Web Client
- Mobile App
- API Gateway
- Application Service
Functional Requirements
- When you transfer $100, you need a guarantee: the money leaves your account and lands in the recipient's account as one atomic operation.
- A partial success is worse than no operation at all.
- When you post a tweet, you do not care if a user in Singapore sees it 500 ms later than a user in New York.
Constraints & Assumptions
- Decision rule of thumb: If your data has money, seats, or contracts in it, lean toward ACID.
- If your data has likes, views, or preferences in it, BASE is usually fine.
β‘ Execution Stages & Decision Trace
Stage 1 β What ACID and BASE Actually Stand For
Before diving into mechanics, let's decode the acronyms in plain language β because both names are deliberately chosen contrasts.
ACID stands for: - A β Atomicity: A transaction is all-or-nothing.
Deep Dive
Scenario context
When you transfer $100, you need a guarantee: the money leaves your account and lands in the recipient's account as one atomic operation. A partial success is worse than no operation at all. This is ACID.
When you post a tweet, you do not care if a user in Singapore sees it 500 ms later than a user in New York. What you care about is that the system stays up and the tweet eventually propagates everywherβ¦
This walkthrough focuses on Why Your Bank and Twitter Run on Different Consistency Rules.
Before making a design choice, clarify:
- When you transfer $100, you need a guarantee: the money leaves your account and lands in the recipient's account as one atomic operation.
- A partial success is worse than no operation at all.
- When you post a tweet, you do not care if a user in Singapore sees it 500 ms later than a user in New York.
Concepts in play: transaction-isolation-distributed-acid, consistency-replication, caching, event-driven-architecture
Stage 1 β What ACID and BASE Actually Stand For
- Before diving into mechanics, let's decode the acronyms in plain language β because both names are deliberately chosen contrasts.
- ACID stands for: - A β Atomicity: A transaction is all-or-nothing.
- Either every step succeeds, or the whole thing is rolled back as if it never happened.
- C β Consistency: A committed transaction always leaves the database in a valid state.
Observable outcome: - C β Consistency: A committed transaction always leaves the database in a valid state.
Stage 2 β ACID Refresher: The Four Promises of Relational Databases
Observable outcome: You can explain how βACID Refresher: The Four Promises of Relational Databasesβ changes the architecture or implementation path.
Stage 3 β BASE in Detail: The Three Properties Unpacked
- B β Basically Available The system returns a response to every request, even if that response is stale or partial.
- Think of Amazon showing a product as "In Stock" based on the last known count, even if the live count hasn't propagated yet.
- S β Soft State The state of the system may change over time even without new input, as consistency information propagates across nodes.
- The data is "in flux" during the window between a write and full propagation.
flowchart LR
Client --> NodeA[Node A Write X=5]
NodeA --> NodeB[Node B X=5 propagates]
NodeA --> NodeC[Node C X=5 propagates]
NodeC --> StaleRead[Stale read X=3 for ~100ms]
NodeB --> FreshRead[Fresh read X=5]
Observable outcome: The data is "in flux" during the window between a write and full propagation.
Stage 4 β Deep Dive: Eventual Consistency and the Shopping Cart
- Amazon's Dynamo paper (2007) used the shopping cart as the canonical example.
- You add "Red Shoes" to your cart on your phone.
- You open your cart on your laptop 200 ms later.
- The write hasn't propagated yet β the laptop sees the old cart (no Red Shoes).
Observable outcome: - The write hasn't propagated yet β the laptop sees the old cart (no Red Shoes).
Stage 5 β Real-World Applications: BASE Systems in the Wild
- Amazon DynamoDB: Eventual consistency by default; strongly consistent reads available with extra cost.
- Apache Cassandra: Tunable consistency β you choose per-query: ONE , QUORUM , or ALL .
- Redis (cache-aside): Classic soft-state β your cache is always slightly behind the source of truth.
- DNS: The most widely used eventually consistent system on earth.
Observable outcome: - DNS: The most widely used eventually consistent system on earth.
Stage 6 β Spring Data + Apache Kafka: @Transactional for ACID, Events for BASE
- Spring Data is the persistence abstraction in the Spring ecosystem, providing @Transactional , JpaRepository , and CrudRepository to deliver ACID semantics over relational databases.
- Apache Kafka is the distributed event streaming platform most commonly used alongside Spring to implement the BASE side β a confirmed write propagates to other services asynchronously via events, achieving eventual consβ¦
- ACID path β Spring @Transactional ensures atomicity across inventory and order writes: BASE path β Kafka event decouples downstream services from the critical transaction: Kafka consumer β BASE eventual consistency on tβ¦
- The Kafka event is BASE: the notification service is eventually consistent β it will process the event, but not within the same atomic boundary.
@Service
@RequiredArgsConstructor
public class OrderService {
private final OrderRepository orderRepository; // JPA β PostgreSQL
private final InventoryRepository inventoryRepository;
private final KafkaTemplate<String, OrderEvent> kafka;
@Transactional // β ACID: both DB writes succeed or both roll back atomically
public Order placeOrder(OrderRequest request) {
// Step 1 β Debit inventory (constraint: stock must not go negative)
Inventory inv = inventoryRepository
.findByProductIdWithLock(request.getProductId()); // SELECT FOR UPDATE
if (inv.getStock() < request.getQuantity()) {
throw new InsufficientStockException("Product out of stock");
}
inv.setStock(inv.getStock() - request.getQuantity());
inventoryRepository.save(inv);
// Step 2 β Create order record in the same transaction
Order order = new Order(
UUID.randomUUID().toString(),
request.getUserId(),
request.getProductId(),
request.getQuantity(),
OrderStatus.CONFIRMED
);
return orderRepository.save(order);
// If any step above throws a RuntimeException,
// @Transactional rolls back BOTH writes β no partial state possible
}
}
Observable outcome: The Kafka event is BASE: the notification service is eventually consistent β it will process the event, but not within the same atomic boundary.
End-to-end outcome
When you transfer $100, you need a guarantee: the money leaves your account and lands in the recipient's account as one atomic operation.
Alternatives considered
Write Flow: ACID vs BASE
The difference between ACID and BASE becomes clearest when you trace a single write through each system.
Decision Guide: ACID or BASE?
Choose your consistency model at design time β not after the first data-loss incident.
Failure and degraded modes
Trade-offs & Failure Modes: ACID vs BASE
- Detection: Decision rule of thumb: If your data has money, seats, or contracts in it, lean toward ACID.
- User or operator impact: Decision rule of thumb: If your data has money, seats, or contracts in it, lean toward ACID.
