Skip to content
LuTiao Programming
Author

LuTiao Programming

LuTiao Programming is a friendly community offering free programming lessons. We inspire learners to explore new ideas and technologies and quickly acquire job-ready skills.

243
Articles
0
Likes
1.8k
Views
0
Comments
Recent Articles

Latest from LuTiao Programming

100 recent articles max
LuTiao Programming
LuTiao Programming
Sep 6, 2026 · Artificial Intelligence

Spring AI 2.0 Tool Search: Stop Flooding LLMs with Dozens of Tools

The author migrates a Spring AI Agent with 30+ business tools to Spring AI 2.0's Tool Search, which uses Lucene indexing to let the model search for relevant tools before calling them, reducing context overload and improving selection accuracy, while sharing best practices for tool descriptions and safe write-operation handling.

AI AgentJavaLucene
0 likes · 15 min read
Spring AI 2.0 Tool Search: Stop Flooding LLMs with Dozens of Tools
LuTiao Programming
LuTiao Programming
Sep 5, 2026 · Backend Development

Why @Scheduled Runs 3× in Kubernetes: Migrating to JobRunr for Distributed Tasks

After scaling a Spring Boot app to three Kubernetes replicas, @Scheduled tasks ran thrice, generating duplicate reports. The author evaluates distributed locks but adopts JobRunr for persistent, retryable, and monitorable background jobs, demonstrating integration with Spring Boot 4, code patterns for fire-and-forget, recurring, and delayed tasks, plus idempotency and deduplication strategies.

Background JobsDistributed Task SchedulingJobRunr
0 likes · 16 min read
Why @Scheduled Runs 3× in Kubernetes: Migrating to JobRunr for Distributed Tasks
LuTiao Programming
LuTiao Programming
Sep 4, 2026 · Backend Development

Spring Boot 4.1 Upgrade: Why Your Decade-Old ObjectMapper Breaks First

This article details the practical challenges and solutions when migrating from Spring Boot 3.x to 4.x, focusing on the Jackson 2 to 3 transition including package changes, exception handling updates, annotation exceptions, immutable ObjectMapper configuration, and coexistence strategies for legacy dependencies.

Backend DevelopmentJSONJackson
0 likes · 16 min read
Spring Boot 4.1 Upgrade: Why Your Decade-Old ObjectMapper Breaks First
LuTiao Programming
LuTiao Programming
Sep 3, 2026 · Backend Development

Kafka 4.2 Share Groups: Can Kafka Replace RabbitMQ for Task Queues?

The author tests Kafka 4.2 Share Groups (Kafka Queues) by migrating a report-generation task queue from RabbitMQ, showing how Share Groups enable elastic consumer scaling beyond partition limits, manual acknowledgment modes (ACCEPT/RELEASE/REJECT/RENEW), and long-task handling with renew(), while noting RabbitMQ's routing strengths remain relevant.

KafkaKafka QueuesMessage Queue
0 likes · 16 min read
Kafka 4.2 Share Groups: Can Kafka Replace RabbitMQ for Task Queues?
LuTiao Programming
LuTiao Programming
Sep 2, 2026 · Backend Development

Spring Boot Multi-Tenancy: Why Data Source Routing Is the Easy Part

This article walks through a production-ready Spring Boot multi-tenancy implementation using database-per-tenant isolation, JWT-based tenant identification via Spring Security, AbstractRoutingDataSource for dynamic routing, and ThreadLocal context management, while exposing critical pitfalls in transaction timing, async task propagation, and dynamic tenant registration.

AbstractRoutingDataSourceDatabase Per TenantJWT
0 likes · 16 min read
Spring Boot Multi-Tenancy: Why Data Source Routing Is the Easy Part
LuTiao Programming
LuTiao Programming
Sep 1, 2026 · Backend Development

Why I Dropped @FeignClient After Years of Use: Spring Boot’s Built‑In HTTP Service Client

The author refactors an old Spring Cloud project by removing Feign, replacing @FeignClient with Spring Boot 4.x’s native @HttpExchange and @ImportHttpServices, and demonstrates that Spring’s built‑in HTTP Service Client provides the same declarative convenience with less boilerplate, while still supporting custom configuration, error handling, and reactive use cases.

Declarative HTTPFeignHTTP Service Client
0 likes · 14 min read
Why I Dropped @FeignClient After Years of Use: Spring Boot’s Built‑In HTTP Service Client
LuTiao Programming
LuTiao Programming
Aug 31, 2026 · Backend Development

Why Disabled Buttons Still Produce Duplicate Orders – Rebuilding Idempotency in Spring Boot

The article examines a common duplicate‑order bug caused by client retries after network timeouts, explains why @Transactional alone cannot guarantee idempotency, critiques simple Redis SETNX solutions, and presents a robust Spring Boot design that stores idempotency records together with order data in a single MySQL transaction, uses request fingerprints, unique keys, and owner tokens to safely replay or reject retries while handling concurrency and cleanup.

@TransactionalAPI DesignJava
0 likes · 19 min read
Why Disabled Buttons Still Produce Duplicate Orders – Rebuilding Idempotency in Spring Boot
LuTiao Programming
LuTiao Programming
Aug 30, 2026 · Databases

I Finally Deleted the Java Code That Reads the Whole Redis Object to Update One Field

The article explains how the old pattern of GET‑ing an entire JSON string from Redis, deserializing it in Java, modifying a single field and writing it back is inefficient and error‑prone, and shows how Spring Data Redis 4.2’s RedisJsonTemplate lets you update or read individual JSON paths directly, reducing code, network traffic and race‑condition risks.

CacheJSONJava
0 likes · 15 min read
I Finally Deleted the Java Code That Reads the Whole Redis Object to Update One Field
LuTiao Programming
LuTiao Programming
Aug 29, 2026 · Backend Development

Dropping findById()+save(): Spring Data Now Handles It with a Single SQL

The article explains how the traditional find‑by‑id‑then‑save pattern causes two database round‑trips and concurrency bugs, and shows that Spring Data 4.1’s single‑statement Upsert (JdbcAggregateTemplate.upsert) lets the database decide INSERT or UPDATE in one SQL, reducing latency and race conditions while outlining its limitations and ideal use cases.

JDBCSpring BootUPSERT
0 likes · 13 min read
Dropping findById()+save(): Spring Data Now Handles It with a Single SQL