Race condition on balance updates: Pessimistic Lock or Redlock?
Keep the invariant in the DB with an atomic `UPDATE ... WHERE balance >= 40` or a `SELECT ... FOR UPDATE`, and save Redlock for non-DB resources.
Just Ask
Ask me anything about software architecture, careers, PHP, Go and the craft of building software; I answer here, in the open, for everyone. (Page 5/8)
Whatever's on your mind, don't hold back. Questions reach me directly; I answer the good ones and publish them on this page. Your email is never published.
Keep the invariant in the DB with an atomic `UPDATE ... WHERE balance >= 40` or a `SELECT ... FOR UPDATE`, and save Redlock for non-DB resources.
Put `tries` and a `backoff` on the job so it lands in `failed_jobs` at the cap, alert from a `JobFailed` listener and replay it with `queue:retry`.
Keep liveness dependency-free and check dependencies in readiness with a cached probe, since liveness restarts the pod while readiness only sheds traffic.
Stand up monthly RANGE declarative partitioning on `created_at`, backfill history in batches while the app writes, then swap names in a single transaction.
Acquire locks in one global order such as ascending PK, keep transactions short, target `FOR UPDATE` at the fewest rows, and retry the rest with backoff.
Wrap requests in a `defer recover()` middleware at the outermost layer, log the stack with the request id, return a generic 500 and emit a metric.
RPO 5min buys continuous cross-region replication and PITR, RTO 30min an IaC-provisioned warm standby behind Route 53 failover, rehearsed on a game-day.
Collapse repeated errors into one counted line, back off retries, cap logrotate by size and count, and give `/var/log` a volume off the root disk.
Per-IP limits lose to rotating proxies, so key the Redis sliding-window on account + IP + ASN, add account lockout and leave volumetric floods to the edge.
Split the critical path (browse, cart, checkout) from the nice-to-haves, put those behind feature flags with short timeouts, and rehearse the kill-switch.