Resilient Retries and Read Replicas in OrmLite
ServiceStack v10.4 lets OrmLite retry temporary database errors such as deadlocks, throttling and failovers through a single configuration line. It also adds read replica support, with read-only connections that reject writes even on the primary so replica bugs surface during development. Both features matter for any .NET app that talks to a database under load.
Key points
- Set OrmLiteConfig.RetryPolicy = OrmLiteRetry.Exponential(maxRetries: 3) to retry temporary errors automatically
- A RunInTransaction block is rolled back and run again as a whole; single statements inside it are not retried alone
- On a lost connection only reads are retried, because a write may already have been saved
- Move side effects like emails and card payments after the transaction commits, since the block may run more than once
- OpenReadOnlyDbConnection() falls back to the primary without a replica, and read-only connections reject writes
- ReadYourWritesFor defaults to 5 seconds so users see their own writes while a replica catches up
ServiceStack v10.4 teaches OrmLite to handle temporary database failures itself. Deadlocks, serialization failures, throttling, failovers and dropped connections can be retried automatically once a RetryPolicy is set, and a RunInTransaction block is rolled back and run again as a whole. Retries use exponential backoff with randomized waits, and each database dialect recognizes its own driver's transient error codes.
The release also adds read replicas. A replica registered with AddReadReplica is used by OpenReadOnlyDbConnection, and without one the call falls back to the primary, so the same code runs in development. Read-only connections refuse writes on every database, including the primary, which exposes the common bug of a write sneaking onto a replica before it reaches production. Because retried transactions can run more than once, side effects such as emails belong after the commit.
Real-world use
- Keeping deadlocks in a high-concurrency balance transfer service from surfacing as user-facing errors
- Offloading report queries from the primary in an ASP.NET Core app to a PostgreSQL standby replica
- Retrying throttled requests with exponential backoff in a SaaS API running on a cloud database
Why it matters
You can drop hand-written retry loops and let OrmLite decide what is safe to repeat. Read-only connections make replica write bugs fail during development instead of in production.
Related stories
- Six common ASP.NET Core Web API mistakes and the patterns to use insteadDEV Community: #aspnetcoreOct 23
- Mastering Rate Limiting and Resource Governance for MCP Servers at ScaleDEV Community: #aspnetcore1 d ago
- Idempotent NebulaGraph bulk ingestion from .NET using deterministic VIDsDEV Community: #csharp3 d ago