blog.suje.sh

Spring Boot

Using Oracle Database with Docker for Spring Boot Integration Testing

Introduction Testing against the same database you use in production is crucial for catching environment-specific bugs early. However, setting up Oracle locally has traditionally been painful—complex licensing, heavy resource requirements, and tedious configuration. Enter Oracle Free (formerly Oracle XE) with Docker. Oracle now provides lightweight, free Docker images that make local Oracle development surprisingly easy. Combined with Spring Boot’s Docker Compose support, you can spin up a real Oracle database automatically when your application starts.

Solving N+1 and Playing with LISTAGG (Oracle/H2)

Over the last few weeks, I’ve been tinkering with some parts of our persistence layer — mostly out of curiosity. I’ve been using Spring Data JPA forever, but recently I started pushing it into areas where the “happy path” begins to crumble: dynamic filtering, projections, and of course… the infamous N+1 problem. During this little experiment, I ended up rediscovering QueryDSL (yes, it still exists, still works, and is still pretty awesome). I also stumbled upon something fun: using LISTAGG (Oracle/H2) to flatten collections in a single query, avoiding N+1 without fetch-joining the universe.

Distributed Locks and Fencing Tokens — Handling Concurrency Safely in Microservices

Over the last few years, I worked mostly on building microservices using Spring Boot, but I never really had a chance to work directly with distributed locking systems like Redis, ZooKeeper, or etcd. Still, I kept coming across these topics whenever I read about system design, schedulers, or how large systems avoid inconsistent updates. I always wanted to understand how distributed locks actually work and what could go wrong when multiple service instances try to modify the same shared resource.

Circuit Breakers, Retries, Backoff, and Timeouts — Making Microservices Resilient

In microservice architectures, things don’t always fail cleanly. Sometimes a service goes down, but more often it just gets slow, times out, or behaves inconsistently. If we don’t handle these failures properly, a small outage in one service can quickly turn into a cascading failure across the whole system. That’s where timeouts, retries, backoff, and circuit breakers come in — four reliability patterns that make microservices resilient instead of fragile.

Understanding Idempotency — Building Reliable APIs and Microservices

For the last few years, I have been working on building Java microservices using Spring Boot. In day-to-day development, I often come across terms like retries, transactions, and duplicate requests, especially when building APIs that interact with other services or databases. While working on one such service recently, I came across the concept of idempotency. It’s one of those ideas that look simple on the surface but play a big role in making systems reliable. I decided to explore it in a bit more detail and write down what I learned here.