Enterprise Spring Boot Architecture & Resilience¶
Purpose & Scope¶
This skill provides standards for structuring enterprise Spring Boot microservices with Spring Data JPA, Spring Security, and Project Loom virtual threads.
Real-Life Incident Case: The Silent HikariCP Connection Leak¶
Background & What Happened¶
Under sudden peak load (8,000 requests/sec), an enterprise banking transaction service stopped responding. CPU on the JVM was low (< 20%), but HTTP 500 errors surged with:
org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction
Caused by: java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30000ms.
Real-Time Live Triage Protocol¶
The SRE agent executed the following live diagnostic steps:
1. Inspect Thread States via JVM Thread Dump¶
# Capture thread dump inside container
jcmd 1 Thread.print > /tmp/threaddump.txt
# Grep for threads blocked on HikariCP borrow
grep -A 10 "HikariPool-1 connection getter" /tmp/threaddump.txt
TIMED_WAITING waiting to borrow a database connection from HikariCP.
2. Inspect Connection Leak Detection Threshold¶
By default, HikariCP does not log unreturned connections. The agent activated leak detection dynamically via Spring Actuator:
curl -X POST http://localhost:8080/actuator/env -H 'Content-Type: application/json' \
-d '{"name":"spring.datasource.hikari.leak-detection-threshold","value":"5000"}'
@Transactional boundary. When the external webhook hung for 25 seconds, the database connection remained locked, draining the pool of all 10 connections.
Production Architecture Standard: Decouple External IO from @Transactional¶
The Anti-Pattern (Connection Leak)¶
@Transactional
public void processOrder(OrderRequest request) {
Order order = orderRepository.save(new Order(request));
// DANGEROUS: Holding DB connection open while performing slow external HTTP IO
paymentGatewayClient.charge(order.getAmount());
}
The Production Standard (Surgical Isolation)¶
@Service
public class OrderService {
private final OrderRepository orderRepository;
private final PaymentGatewayClient paymentGatewayClient;
public void processOrder(OrderRequest request) {
// 1. Database write in short-lived transaction
Order order = savePendingOrder(request);
// 2. Slow external network call executed OUTSIDE transaction boundary
PaymentResult result = paymentGatewayClient.charge(order.getAmount());
// 3. Second short-lived transaction to update final status
updateOrderStatus(order.getId(), result.getStatus());
}
@Transactional
public Order savePendingOrder(OrderRequest request) {
return orderRepository.save(new Order(request));
}
@Transactional
public void updateOrderStatus(Long orderId, String status) {
orderRepository.updateStatus(orderId, status);
}
}
Continuous Self-Knowledge Enhancement Loop¶
When the agent triages a connection exhaustion outage:
1. Isolate Architectural Flaw: Detect @Transactional wrapping external network or messaging calls.
2. Auto-Generate Static Analysis Rule: Add an architectural check in agents/7-agent-master-suite/devsecops-reviewer.md to flag @Transactional on methods calling external REST/gRPC clients.
3. Update Memory: Record the HikariCP leak-detection-threshold debugging trick in AGENTS.md under ## Learned JVM Runtime Facts.