One of the most abused annotations in Spring is @Transactional. People treat it like a “wrap everything and forget” switch. I’ve seen methods like this: 👉 save to DB 👉 call external payment API 👉 send email 👉 call another microservice 👉 update DB again All inside ONE transaction. Looks clean. Feels safe. It’s not. Because the moment you mix DB + external calls inside a transaction, things start getting messy: ⚠️ external APIs are slow ⚠️ transactions stay open longer (locks, performance issues) ⚠️ if API fails → DB rolls back, but external system doesn’t ⚠️ debugging becomes painful Now you have inconsistent systems and no clear recovery path. The better way? Keep @Transactional boring. ✔️ only DB operations inside ✔️ keep it short ✔️ do external calls before or after ✔️ think about failure scenarios explicitly @Transaction is not a safety net. It’s a boundary. Use it wrong → hidden bugs Use it right → stable systems Learned this the hard way 🙂 #Java #SpringBoot #BackendEngineering #SystemDesign #Microservices #CodeQuality
Avoid Mixing DB and External Calls in @Transactional
More Relevant Posts
-
💡 A simple backend decision that improved performance (by doing less) Recently, I was working on a flow where we select a provider based on its previous status stored in the database. The requirement was simple: 👉 If the last attempt failed, don’t pick the same provider again. My first approach? Fetch the entire history and decide based on that. It worked — but it didn’t feel right. After rethinking the problem, I realized: I only needed the latest record, not the full history. So I refactored the logic to fetch just the most recent entry. That small change led to: ✔️ Reduced database load ✔️ Simpler, cleaner logic ✔️ Faster decision-making in the flow What stood out to me was this: 👉 We often over-engineer solutions trying to cover every edge case, when the actual requirement is much simpler. In backend systems, clarity and efficiency usually win over complexity. Still learning to identify these moments early — but each one makes a difference. #BackendDevelopment #Java #SpringBoot #SystemDesign #CleanCode #SoftwareEngineering
To view or add a comment, sign in
-
The service was up. The API was up. The database was up. Users were still complaining. That’s why I think a lot of engineers misunderstand reliability. They think reliability means keeping components alive. It doesn’t. It means keeping the full user path stable when systems start interacting badly. A service can be healthy. A dashboard can be green. And the product can still feel broken. Because real pain usually comes from: - slow dependencies - retry amplification - fragile request paths - components that are “up” but harmful together Debate: What do engineers misunderstand more often? A) scalability B) reliability My vote: B. What’s yours? #Java #SpringBoot #DistributedSystems #Microservices #BackendEngineering
To view or add a comment, sign in
-
Day 24. My API was fast. Until it wasn't. I had this: return ResponseEntity.ok(userRepository.findAll()); 10 users in development. Works instantly. Feels perfect. Then production happened: → 50,000 users in the database → One API call loads everything → Response time: 40ms → 8 seconds → Memory spikes → API crashes That's not a performance issue. That's a design mistake. And it was there from day one. I just couldn't see it yet. That's when it clicked: Your API should never decide how much data to return. The client should. So I added pagination. (see implementation below 👇) What changed: → Performance — stable response time → Scalability — works at 100 or 100,000 rows → Stability — no memory spikes The hard truth: → findAll() works in tutorials → It breaks in production → Pagination is not an optimization — it's a requirement Fetching data is easy. Controlling how much you fetch is what makes your API scalable. Are you still using findAll() in production? 👇 Drop it below #SpringBoot #Java #BackendDevelopment #Performance #JavaDeveloper
To view or add a comment, sign in
-
-
Day 27. I put @Transactional in my controller. My senior caught it in code review. That conversation changed how I think about layers. I had this: @RestController public class UserController { @Transactional @PostMapping("/users") public ResponseEntity<?> createUser(@RequestBody User user) { userRepository.save(user); return ResponseEntity.ok("User created"); } } It worked. No errors. Everything looked fine. Looked clean. Until a senior looked at it. Here’s what actually happens: → Transaction starts at the controller → It stays open longer than needed → Higher chance of locks & performance issues → Blurred business logic boundaries That’s when it clicked. Transactions don’t belong in controllers. Controllers should: → Handle HTTP → Delegate work Not manage transactions. So I changed it. (see implementation below 👇) What I learned: → Transactions define business boundaries → They should live close to business logic (service layer) → Not at the API layer The hard truth: → Working code and well-designed code are two different things → Most tutorials only teach you the first one Writing working code is easy. Placing responsibility in the right layer is what makes you a backend developer. If your senior reviewed your controller today — would @Transactional be there? 👇 Drop your take #SpringBoot #Java #BackendDevelopment #CleanCode #Hibernate #JavaDeveloper
To view or add a comment, sign in
-
-
A subtle Spring behavior that causes real production issues: @Transactional propagation. Most people rely on the default propagation without thinking about transaction boundaries. Example: Method A → @Transactional (REQUIRED) calls Method B → @Transactional (REQUIRES_NEW) What actually happens? Method B runs in a NEW transaction. So even if Method A fails and rolls back, Method B can still commit ❌ Result: Partial data committed → inconsistent state Fix: • Use REQUIRED if operations must succeed or fail together • Use REQUIRES_NEW only when you intentionally need an independent transaction (e.g., audit/logging) • Define transaction boundaries clearly at the service layer Seen this during backend development while handling dependent operations. Lesson: Don’t rely on defaults — design your transaction boundaries consciously. #SpringBoot #Java #Transactions #Microservices #Backend #SoftwareEngineering
To view or add a comment, sign in
-
#Post6 In the previous posts, we built basic REST APIs step by step. But what happens when something goes wrong? 🤔 Example: User not found Invalid input Server error 👉 By default, Spring Boot returns a generic error response. But in real applications, we need proper and meaningful error handling. That’s where Exception Handling comes in 🔥 Instead of handling exceptions in every method, Spring provides a better approach using @ControllerAdvice 👉 It allows us to handle exceptions globally Example: @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public String handleException(Exception ex) { return ex.getMessage(); } } 💡 Why use this? • Centralized error handling • Cleaner controller code • Better API response Key takeaway: Use global exception handling to manage errors in a clean and scalable way 🚀 In the next post, we will create custom exceptions for better control 🔥 #Java #SpringBoot #BackendDevelopment #RESTAPI #LearnInPublic
To view or add a comment, sign in
-
🚀 Spring Boot – User API Upgrade (Full CRUD) Took my mini project to the next level by implementing complete CRUD operations in Spring Boot. 🧠 What I added: ✔️ GET "/users" → Fetch all users ✔️ PUT "/user/{id}" → Update user ✔️ DELETE "/user/{id}" → Delete user 💡 Now the API supports full lifecycle operations: Create • Read • Update • Delete 🔁 Architecture in action: Controller → Service → In-memory data → JSON response 🧪 Tested all endpoints using Postman and verified the complete flow. ⚠️ Also understood the importance of proper error handling (next step: exception handling instead of returning null). 💻 DSA Practice: • Move zeros to end (array manipulation) • First non-repeating character (HashMap concept) ✨ This step helped me understand how real backend systems manage and manipulate data efficiently. #SpringBoot #Java #BackendDevelopment #RESTAPI #CRUD #DSA #LearningInPublic #SoftwareEngineering
To view or add a comment, sign in
-
🚀 Spring Boot – Full Flow & Clean Architecture Today I focused on understanding the complete end-to-end flow of a Spring Boot application and how real-world backend systems are structured. 🧠 Core Flow: Client → Controller → DTO (Validation) → Service → Repository → Database → JSON Response ⚠️ Error Flow: Validation/Exception → Global Handler → Structured Error Response 💡 Key Learnings: ✔️ DTO handles validation and safe data transfer ✔️ Service layer contains business logic (application brain) ✔️ Repository interacts with the database using JPA ✔️ Global exception handling ensures clean and consistent APIs 🏗️ Project Structure (Industry Standard): controller • service • repository • dto • entity • exception • config ✨ This separation of concerns makes applications scalable, maintainable, and team-friendly. 💻 DSA Practice: • Two Sum (HashMap optimization) • Reverse string & valid palindrome 🔍 Understanding how each layer connects has given me much better clarity on building production-ready backend systems. #SpringBoot #Java #BackendDevelopment #RESTAPI #Microservices #CleanArchitecture #DSA #LearningInPublic #SoftwareEngineering
To view or add a comment, sign in
-
🚨 Fetching all data from DB is a silent performance killer I once saw an API fetching 50,000 records in one go. 💥 Result: High memory usage Slow response Occasional crashes ✅ Fix: Used pagination: Pageable pageable = PageRequest.of(page, size); 💡 Bonus: Added sorting + limit control from API 💡 Takeaway: Never trust frontend to “handle large data” Backend should enforce limits. #Java #SpringBoot #BackendDevelopment #SoftwareEngineering #Microservices #JPA #RESTAPI #DeveloperLife #CareerGrowth
To view or add a comment, sign in
-
Lessons from Real Backend Systems Short reflections from building and maintaining real backend systems — focusing on Java, distributed systems, and the tradeoffs we don’t talk about enough. ⸻ We had logs everywhere. Still couldn’t explain the outage. At first, it didn’t make sense. Every service was logging. Errors were captured. Dashboards were green just minutes before the failure. But when the system broke, the answers weren’t there. What we had: [Service A Logs] [Service B Logs] [Service C Logs] What we needed: End-to-end understanding of a single request The issue wasn’t lack of data. It was lack of context. Logs told us what happened inside each service. They didn’t tell us how a request moved across the system. That’s when we realized: Observability is not about collecting signals. It’s about connecting them. At scale, debugging requires three perspectives working together: Logs → What happened? Metrics → When and how often? Traces → Where did it happen across services? Without correlation, each signal is incomplete. The turning point was introducing trace context propagation. [Request ID / Trace ID] ↓ Flows across all services ↓ Reconstruct full execution path Now, instead of guessing: * We could trace a failing request across services * Identify latency bottlenecks precisely * Understand failure propagation Architectural insight: Observability should be designed alongside the system — not added after incidents. If you cannot explain how a request flows through your system, you cannot reliably debug it. Takeaway: Logs help you inspect components. Observability helps you understand systems. Which signal do you rely on most during incidents — logs, metrics, or traces? — Writing weekly about backend systems, architectural tradeoffs, and lessons learned through production systems. Keywords: #Observability #DistributedSystems #SystemDesign #BackendEngineering #SoftwareArchitecture #Microservices #Tracing #Monitoring #ScalableSystems
To view or add a comment, sign in
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development