Introduction A single-threaded Spring Batch step processes one chunk at a time — read N items, process N items, write N items, repeat. For large data sets this is a bottleneck. Spring Batch offers two in-JVM scaling options: Approach How it works Use when Multi-threaded step Multiple threads each process independent chunks Reader is thread-safe (JdbcPagingItemReader) AsyncItemProcessor Processing runs concurrently; writes remain sequential I/O-bound processors (REST calls, slow enrichment) This article covers both, plus the thread-safety requirements you must meet.
Continue reading »Spring-Boot
209 posts in this section
Non-Blocking Retries: @RetryableTopic, BackOff, and the Retry Topic Chain
The Blocking Retry Problem DefaultErrorHandler retries by seeking back to the failed offset. While retrying, no other records from that partition are consumed — the partition is blocked. For a topic with high throughput, one slow retry can cause significant consumer lag. flowchart TD subgraph Blocking["Blocking Retry (DefaultErrorHandler)"] B1["poll() → [r50, r51, r52, r53]"] B2["process r50 ✓"] B3["process r51 ✗ — retry"] B4["wait 10s... retry r51 ✗"] B5["wait 20s... retry r51 ✗"
Continue reading »OAuth2 Fundamentals: Grant Types and Flows
OAuth2 in One Sentence OAuth2 lets a user grant a third-party application limited access to their account on another service — without giving the third party their password. Classic example: “Sign in with Google.” Your app never sees the user’s Google password. Google verifies the user’s identity and gives your app a token with limited permissions. The Four OAuth2 Roles flowchart TD RO["**Resource Owner**\nThe user who owns the data\n(e.g. Alice, the Google account owner)"
Continue reading »OAuth2 Login: Sign In with Google, GitHub, and Custom Providers
What OAuth2 Login Does OAuth2LoginConfigurer implements the Authorization Code flow for user authentication. When a user clicks “Sign in with Google”: Spring redirects to Google’s /authorize endpoint User authenticates on Google and grants consent Google redirects back to your app with a code Spring exchanges the code for tokens (back channel) Spring fetches the user profile from /userinfo Spring creates an OAuth2User and stores it in the SecurityContext Dependencies <dependency> <groupId>org.
Continue reading »OAuth2 Resource Server: Protecting APIs with Bearer Tokens
What Is a Resource Server? In OAuth2, a Resource Server is an API that accepts access tokens and returns protected resources. It doesn’t issue tokens — that’s the Authorization Server’s job. The Resource Server just validates tokens and enforces access control. flowchart LR Client[API Client\nor SPA/Mobile] -->|"1. POST /token\n{client_id, secret}"| AS[Authorization Server\nGoogle / Okta / Custom] AS -->|"2. access_token"| Client Client -->|"3. GET /api/products\nAuthorization: Bearer {token}"| RS[Your Spring Boot API\nResource Server] RS -->|"
Continue reading »Offset Management: Auto-Commit vs Manual Acknowledgment
Why Offset Management Matters The committed offset determines what happens when a consumer restarts. If the offset is committed too early, a crash before processing completes means events are lost. If it is committed too late, a crash after processing but before committing means events are re-processed. flowchart TD subgraph TooEarly["Commit too early → Data Loss"] E1["Commit offset 43"] --> E2["Process record 42"] --> E3["Crash!"] E4["Restart: resume from 43"] --> E5["
Continue reading »One-to-Many and Many-to-One: The Most Common Relationship
Introduction The one-to-many relationship is the most common in any domain model. An Order has many OrderItems. A Category has many Products. A Customer has many Orders. Understanding @OneToMany and @ManyToOne well — especially bidirectional mapping, collection types, and cascade configuration — is foundational to any JPA application. The Domain Example orders (1) ──────────────── (*) order_items An order has many order items. Each order item belongs to exactly one order.
Continue reading »One-to-One Relationships: @OneToOne in Depth
Introduction A one-to-one relationship means one record in table A corresponds to exactly one record in table B. In JPA this is modelled with @OneToOne. Understanding where the foreign key lives, which side “owns” the relationship, and how cascade operations work is essential before moving to the more complex @OneToMany and @ManyToMany. The Domain Example In the e-commerce system, a Customer has one CustomerProfile containing their preferences and biography. A profile belongs to exactly one customer.
Continue reading »Optimistic and Pessimistic Locking: Handling Concurrent Updates
The Lost Update Problem Two users edit the same product simultaneously: Time User A User B T1 Load product (price=999) Load product (price=999) T2 Change price to 899 T3 Change price to 799 T4 Save → UPDATE price=899 T5 Save → UPDATE price=799 User A’s change is silently overwritten. This is the lost update problem. Both JPA locking strategies prevent it — in different ways. Optimistic Locking with @Version Optimistic locking assumes conflicts are rare.
Continue reading »Pagination and Sorting with Pageable, Page, and Slice
Why Pagination Matters Returning all rows from a database table is one of the most common production incidents. A query that works in development with 100 rows silently becomes a 10-second, 2 GB memory spike when production has 2 million rows. Pagination limits how many rows travel from the database to the application at a time. Spring Data JPA makes pagination a first-class feature — pass a Pageable to any repository method and get a Page<T> back.
Continue reading »