Spring production failure dojo
장애를 설명하지 않는다.직접 만들고, 숫자로 목격한다.
STAMP 05 · lost-update repair workshop
같은 1000을 읽은 두 debit이 왜 800이 되지 않는지 trace에서 잡는다
Fixed incident: balance 1000 · worker A/B each debit 100 · serial business invariant 800 · PostgreSQL READ COMMITTED.
SOURCE
exact backend strategy class excerpt
SERVER
strategy ID → precompiled Spring path
NOT CLAIMED
browser Java compilation or arbitrary execution
whole system · evidence stays attached to its layer
한 HTTP request 안에서 두 DB transaction이 갈라졌다가 다시 합쳐진다
- 01Browsersource + prediction
- 02Next gatewayallowlist + rate/gate
- 03Tomcatrequest coordinator
- 04JVM workers2 transaction threads
- 05Hikaribounded JDBC sessions
- 06PostgreSQLrow · version · lock
JVM CPUNOT OBSERVED
scheduler time · saturation
JVM MEMORYNOT OBSERVED
heap · allocation · GC
NETWORKNOT OBSERVED
RTT · request/response bytes
PG RESOURCESNOT OBSERVED
CPU · buffers · disk reads
PostgreSQL lock wait is separately MEASURED through pg_stat_activity + pg_blocking_pids. The four machine-resource groups above remain NOT OBSERVED.
single exact strategy-excerpt editor · src-d4fced0b
Read then absolute write
Review question: What happens when both transactions calculate the same absolute balance before either commit is visible?
The displayed class excerpt is normalized directly against LostUpdateStrategies.java and stays in the browser. Only its derived strategy ID is sent; the server executes that precompiled class in the Spring image.
Review the first source and lock a prediction before reproducing the incident.