Your transaction works perfectly… ✅ Until you call 𝗮𝗻𝗼𝘁𝗵𝗲𝗿 𝗺𝗲𝘁𝗵𝗼𝗱 inside it. Suddenly things behave… differently. Why? 𝗣𝗿𝗼𝗽𝗮𝗴𝗮𝘁𝗶𝗼𝗻. If you’re using `@Transactional` and not thinking about propagation, you’re basically saying: “Spring… you decide.” So what is propagation? It defines how a transaction behaves when one method calls another. Simple idea. But huge impact. Let’s break it down with real-world scenarios 🔹 REQUIRED (default) “Join if exists, else create” 💡 Example: Placing an order → Payment service called Both run in the "same transaction". If payment fails → everything rolls back. 🔹 REQUIRES_NEW “Always start fresh” 💡 Example: Order fails ❌ But you still want to "log the failure" Logging runs in a separate transaction → it gets saved ✅ 🔹 SUPPORTS “Join if exists, else run without transaction” 💡 Example: Fetching optional audit data Transaction or not… it doesn’t care. 🔹 NOT_SUPPORTED “Run without transaction” 💡 Example: Heavy read operation where transaction overhead is unnecessary Suspends existing transaction ⏸️ 🔹 MANDATORY “Transaction must exist” 💡 Example: Critical financial operation If no transaction → throw error 🚨 🔹 NEVER “Transaction must NOT exist” 💡 Example: A method that should never be part of a transaction If one exists → exception 💥 🔹 NESTED “Transaction inside a transaction” 💡 Example: Partial rollback scenario Inner transaction fails → outer can still continue Here’s the real insight Most bugs in transaction handling don’t come from syntax… They come from 𝘄𝗿𝗼𝗻𝗴 𝗽𝗿𝗼𝗽𝗮𝗴𝗮𝘁𝗶𝗼𝗻 choices. Using `@Transactional` is easy. Using it correctly is what makes you a solid backend developer. Next time you add `@Transactional`, don’t stop there… Ask: “How should this transaction behave?” #CoreJava #SpringBoot #JavaDeveloper #Transactional #BackendDevelopment #SoftwareEngineering #Developers #Programming #Developers #RDBMS #SQL #JPA #Hibernate #Database #Microservices #aswintech #SystemDesign
Transaction Propagation in Spring: Understanding the Choices
More Relevant Posts
-
🚀 Most developers use @Transactional… but don’t understand how it actually works. And that’s where bugs start. Let’s simplify it 👇 --- 👉 What does @Transactional do? It ensures that a group of database operations: ✔ Either ALL succeed ✔ Or ALL fail (rollback) --- 💡 Example: @Transactional public void placeOrder() { saveOrder(); makePayment(); } 👉 If makePayment() fails ❌ → saveOrder() will also be rolled back --- 🔥 But here’s the catch (VERY IMPORTANT): @Transactional works using Spring AOP (proxy) 👉 Spring creates a proxy around your class → That proxy manages transaction start/commit/rollback --- ⚠️ Common mistake (many developers miss this): @Service public class OrderService { @Transactional public void createOrder() { saveOrder(); // ❌ Transaction may NOT work } @Transactional public void saveOrder() { // DB logic } } 👉 Why? Because internal method calls bypass the proxy 😮 --- ❌ Result: Transaction might not be applied properly --- ✅ Fix: Option 1: Call method from another service (bean) Option 2: Design properly (separate responsibilities) --- 🔥 Real-world impact: In payment systems: ❌ Partial data saved ❌ Inconsistent state This can cause serious bugs 🚨 --- 📌 Key Takeaway: @Transactional is NOT magic → It depends on proxy behavior Understand this = avoid production bugs --- Follow for more real backend learnings 🚀 #SpringBoot #Java #BackendDevelopment #SystemDesign #SoftwareEngineer
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
-
-
In a Spring Boot application, code is structured into layers to keep things clean, maintainable, and scalable. The most common layers are Controller, Service, and Repository each with a clear responsibility. i)Controller * Entry point of the application. * Handles incoming HTTP requests (GET, POST, etc.). * Accepts request data (usually via DTOs). * Returns response to the client. ii)Service * Contains business logic. * Processes and validates data. * Converts DTO ↔ Entity. iii)Repository * Connects with the database. * Performs CRUD operations. * Works directly with Entity objects. Request Flow (Step-by-Step): Let’s understand what happens when a user sends a request: 1. Client sends request Example: `POST /users` with JSON data. 2. Controller receives request * Maps request to a method. * Accepts data in a DTO. ``` @PostMapping("/users") public UserDTO createUser(@RequestBody UserDTO userDTO) { return userService.createUser(userDTO); } ``` 3. Controller → Service * Passes DTO to Service layer. 4. Service processes data * Applies business logic. * Converts DTO → Entity. ``` User user = new User(); user.setName(userDTO.getName()); ``` 5. Service → Repository * Calls repository to save data. ``` userRepository.save(user); ``` 6. Repository → Database * Data is stored in DB. 7. Response Flow Back * Repository → Service → Controller. * Entity converted back to DTO. * Response sent to client. Why DTO is Used: * Prevents exposing internal entity structure. * Controls input/output data. * Improves security. * Keeps layers independent. Why This Architecture Matters: * Clear separation of concerns * Easier debugging & testing * Scalable and maintainable codebase #Java #Spring #SpringBoot #BackendDevelopment #SoftwareEngineering #JavaDeveloper
To view or add a comment, sign in
-
-
𝐄𝐯𝐞𝐫 𝐰𝐨𝐧𝐝𝐞𝐫𝐞𝐝 𝐰𝐡𝐚𝐭 𝐚𝐜𝐭𝐮𝐚𝐥𝐥𝐲 𝐡𝐚𝐩𝐩𝐞𝐧𝐬 𝐰𝐡𝐞𝐧 𝐲𝐨𝐮 𝐡𝐢𝐭 𝐚𝐧 𝐀𝐏𝐈 𝐞𝐧𝐝𝐩𝐨𝐢𝐧𝐭? You click a button… And data magically appears. But behind the scenes? There’s a full backend pipeline running in milliseconds ⚡ Let’s break it down 👇 🌐 𝟏. 𝐃𝐍𝐒 𝐑𝐞𝐬𝐨𝐥𝐮𝐭𝐢𝐨𝐧 You hit: 👉 api.example.com DNS converts it into: 👉 IP address (e.g., 142.x.x.x) No DNS → No connection. 🔐 𝟐. 𝐓𝐂𝐏 + 𝐓𝐋𝐒 𝐇𝐚𝐧𝐝𝐬𝐡𝐚𝐤𝐞 Before data flows: • TCP connection is established • TLS handshake secures it (HTTPS 🔒) 👉 This ensures encrypted communication ⚖️ 𝟑. 𝐋𝐨𝐚𝐝 𝐁𝐚𝐥𝐚𝐧𝐜𝐞𝐫 Request doesn’t go to just one server. It hits a load balancer which: • Distributes traffic • Prevents overload • Improves availability 🚪 𝟒. 𝐀𝐏𝐈 𝐆𝐚𝐭𝐞𝐰𝐚𝐲 / 𝐑𝐞𝐯𝐞𝐫𝐬𝐞 𝐏𝐫𝐨𝐱𝐲 Acts like a gatekeeper: • Authentication (JWT, API keys) • Rate limiting • Routing to correct service ⚙️ 𝟓. 𝐀𝐩𝐩𝐥𝐢𝐜𝐚𝐭𝐢𝐨𝐧 𝐒𝐞𝐫𝐯𝐞𝐫 (𝐒𝐩𝐫𝐢𝐧𝐠 𝐁𝐨𝐨𝐭) Now your Java app kicks in: 👉 Controller → Service → Repository • Business logic runs • Validations happen • Data is prepared 🗄️ 𝟔. 𝐃𝐚𝐭𝐚𝐛𝐚𝐬𝐞 / 𝐂𝐚𝐜𝐡𝐞 App fetches data from: • Database (MySQL, PostgreSQL) • Cache (Redis for speed ⚡) 👉 Good systems always try cache first 🔄 𝟕. 𝐑𝐞𝐬𝐩𝐨𝐧𝐬𝐞 𝐅𝐥𝐨𝐰 Data travels back: Server → Gateway → Load Balancer → Client All in a few milliseconds. 🧠 𝐖𝐡𝐚𝐭 𝐦𝐨𝐬𝐭 𝐝𝐞𝐯𝐬 𝐦𝐢𝐬𝐬 An API call is NOT just a function call. It’s: 👉 Networking 👉 Security 👉 Scalability 👉 System design 🎯 𝐓𝐡𝐞 𝐫𝐞𝐚𝐥 𝐬𝐡𝐢𝐟𝐭 Beginner: 👉 “I created an API” Engineer: 👉 “I understand how requests flow through systems” Next time you hit an API… Remember — a lot more is happening than you think. Which part of this flow did you not know before? 👇 #Backend #Java #SystemDesign #APIs #SoftwareEngineering
To view or add a comment, sign in
-
APIs started making sense to me when I stopped memorizing… and started understanding the flow 👇 At a basic level, an API is just a way for systems to communicate. But what actually happens when you hit an API? Let’s break it down: 1️⃣ Client sends a request Example: GET /users/1 2️⃣ Request reaches the server → Routed to the correct controller 3️⃣ Business logic runs → Service layer processes the request 4️⃣ Database interaction → Fetch / update data 5️⃣ Response is returned → Usually JSON So the real flow is: 👉 Client → Controller → Service → Database → Response What helped me most was understanding this: • APIs are not just endpoints • They are structured layers working together Also, things started clicking when I focused on: • HTTP methods (GET, POST, PUT, DELETE) • Status codes (200, 404, 500) • Request & response structure Still learning, but understanding this flow made backend development much clearer. If you're learning APIs, focus on the flow — not just the syntax. #BackendDevelopment #APIs #Java #SpringBoot #WebDevelopment #Developers #LearningInPublic
To view or add a comment, sign in
-
-
☁️ 𝗪𝗵𝗮𝘁 𝗶𝘀 𝟭𝟮-𝗙𝗮𝗰𝘁𝗼𝗿 𝗔𝗽𝗽 𝗺𝗲𝘁𝗵𝗼𝗱𝗼𝗹𝗼𝗴𝘆? The Twelve-Factor App is a set of 12 best practices to build scalable, maintainable, and cloud-ready applications. 🚀 The 12 Factors (Simple + Interview Ready) 𝟭. 📦 𝗖𝗼𝗱𝗲𝗯𝗮𝘀𝗲 👉 One codebase tracked in version control (Git) Multiple deploys (dev, QA, prod) 𝟮. 📚 𝗗𝗲𝗽𝗲𝗻𝗱𝗲𝗻𝗰𝗶𝗲𝘀 👉 Explicitly declare dependencies 𝗨𝘀𝗲 𝗠𝗮𝘃𝗲𝗻 / 𝗚𝗿𝗮𝗱𝗹𝗲 (𝗝𝗮𝘃𝗮) 3. ⚙️ Config 👉 Store config in environment variables No hardcoding Example: DB URL, API keys 𝟰. 🧩 𝗕𝗮𝗰𝗸𝗶𝗻𝗴 𝗦𝗲𝗿𝘃𝗶𝗰𝗲𝘀 👉 Treat DB, cache, messaging as attached resources Easily replaceable (e.g., MySQL → PostgreSQL) 𝟱. 🔨 𝗕𝘂𝗶𝗹𝗱, 𝗥𝗲𝗹𝗲𝗮𝘀𝗲, 𝗥𝘂𝗻 👉 Separate: Build → compile Release → config Run → execution 𝟲. 🧱 𝗣𝗿𝗼𝗰𝗲𝘀𝘀𝗲𝘀 👉 App runs as stateless processes No session stored in memory 𝟳. 🌐 𝗣𝗼𝗿𝘁 𝗕𝗶𝗻𝗱𝗶𝗻𝗴 👉 App exposes service via port Example: Spring Boot runs on 8080 𝟴. ⚡ 𝗖𝗼𝗻𝗰𝘂𝗿𝗿𝗲𝗻𝗰𝘆 👉 Scale via multiple processes Horizontal scaling (more instances) 𝟵. 🔄 𝗗𝗶𝘀𝗽𝗼𝘀𝗮𝗯𝗶𝗹𝗶𝘁𝘆 👉 Fast startup & graceful shutdown Important for containers (Docker) 𝟭𝟬. 🧪 𝗗𝗲𝘃/𝗣𝗿𝗼𝗱 𝗣𝗮𝗿𝗶𝘁𝘆 👉 Keep dev, QA, prod environments similar Avoid “works on my machine” issues 𝟭𝟭. 📊 𝗟𝗼𝗴𝘀 👉 Treat logs as event streams Don’t store locally → use ELK / Splunk 𝟭𝟮. 🛠️ 𝗔𝗱𝗺𝗶𝗻 𝗣𝗿𝗼𝗰𝗲𝘀𝘀𝗲𝘀 👉 Run admin tasks as one-off processes Example: DB migration scripts 🎯 Interview Short Answer The 12-factor app is a methodology for building cloud-native applications. It includes principles like using a single codebase, managing configurations via environment variables, keeping applications stateless, enabling horizontal scaling, and maintaining dev-prod parity to ensure scalability and maintainability. #systendesign #cloud #java
To view or add a comment, sign in
-
-
A solid reminder of how building scalable, maintainable, and cloud-native applications requires strong foundational principles. From configuration management to stateless processes and efficient dependency handling — every factor plays a crucial role in modern application design. Really valuable insights for anyone working on distributed systems or cloud-based architectures. Kudos to the author for putting together such a practical and insightful post! 🚀 #SoftwareEngineering #CloudNative #12FactorApp #SystemDesign #Microservices #DevOps #Architecture
☁️ 𝗪𝗵𝗮𝘁 𝗶𝘀 𝟭𝟮-𝗙𝗮𝗰𝘁𝗼𝗿 𝗔𝗽𝗽 𝗺𝗲𝘁𝗵𝗼𝗱𝗼𝗹𝗼𝗴𝘆? The Twelve-Factor App is a set of 12 best practices to build scalable, maintainable, and cloud-ready applications. 🚀 The 12 Factors (Simple + Interview Ready) 𝟭. 📦 𝗖𝗼𝗱𝗲𝗯𝗮𝘀𝗲 👉 One codebase tracked in version control (Git) Multiple deploys (dev, QA, prod) 𝟮. 📚 𝗗𝗲𝗽𝗲𝗻𝗱𝗲𝗻𝗰𝗶𝗲𝘀 👉 Explicitly declare dependencies 𝗨𝘀𝗲 𝗠𝗮𝘃𝗲𝗻 / 𝗚𝗿𝗮𝗱𝗹𝗲 (𝗝𝗮𝘃𝗮) 3. ⚙️ Config 👉 Store config in environment variables No hardcoding Example: DB URL, API keys 𝟰. 🧩 𝗕𝗮𝗰𝗸𝗶𝗻𝗴 𝗦𝗲𝗿𝘃𝗶𝗰𝗲𝘀 👉 Treat DB, cache, messaging as attached resources Easily replaceable (e.g., MySQL → PostgreSQL) 𝟱. 🔨 𝗕𝘂𝗶𝗹𝗱, 𝗥𝗲𝗹𝗲𝗮𝘀𝗲, 𝗥𝘂𝗻 👉 Separate: Build → compile Release → config Run → execution 𝟲. 🧱 𝗣𝗿𝗼𝗰𝗲𝘀𝘀𝗲𝘀 👉 App runs as stateless processes No session stored in memory 𝟳. 🌐 𝗣𝗼𝗿𝘁 𝗕𝗶𝗻𝗱𝗶𝗻𝗴 👉 App exposes service via port Example: Spring Boot runs on 8080 𝟴. ⚡ 𝗖𝗼𝗻𝗰𝘂𝗿𝗿𝗲𝗻𝗰𝘆 👉 Scale via multiple processes Horizontal scaling (more instances) 𝟵. 🔄 𝗗𝗶𝘀𝗽𝗼𝘀𝗮𝗯𝗶𝗹𝗶𝘁𝘆 👉 Fast startup & graceful shutdown Important for containers (Docker) 𝟭𝟬. 🧪 𝗗𝗲𝘃/𝗣𝗿𝗼𝗱 𝗣𝗮𝗿𝗶𝘁𝘆 👉 Keep dev, QA, prod environments similar Avoid “works on my machine” issues 𝟭𝟭. 📊 𝗟𝗼𝗴𝘀 👉 Treat logs as event streams Don’t store locally → use ELK / Splunk 𝟭𝟮. 🛠️ 𝗔𝗱𝗺𝗶𝗻 𝗣𝗿𝗼𝗰𝗲𝘀𝘀𝗲𝘀 👉 Run admin tasks as one-off processes Example: DB migration scripts 🎯 Interview Short Answer The 12-factor app is a methodology for building cloud-native applications. It includes principles like using a single codebase, managing configurations via environment variables, keeping applications stateless, enabling horizontal scaling, and maintaining dev-prod parity to ensure scalability and maintainability. #systendesign #cloud #java
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
-
Why CRUD thinking is not enough for serious backend systems Not every business problem should be modeled as simple CRUD A lot of applications start as: - Create - Read - Update - Delete And that’s fine in simple cases. But serious business systems usually have behaviors that are not well represented by CRUD. An order is not just “updated”. It can be: - placed - confirmed - cancelled - paid - expired - refunded Inventory is not just “edited”. It can be: - reserved - released - restocked - confirmed Once you model everything as generic updates, you start losing business meaning. That’s when bugs increase. Because the system no longer expresses the real rules clearly. Good backend design often means moving from: data manipulation to business behavior modeling That’s a major difference between simple coding and system design. #DDD #BackendEngineering #Java #SpringBoot #SystemDesign #SoftwareArchitecture
To view or add a comment, sign in
-
-
Returning your database Entity directly in your API is a ticking time bomb. Early in my career, I built a simple user profile API. To save time, I just returned the JPA User entity directly from the controller. It worked perfectly, the code was clean, and the PR was approved. A few months later, another developer added a password_hash and two_factor_secret column to the database table to support a new security feature. Because my API was returning the raw entity, it automatically started serializing those new columns. We were suddenly leaking password hashes directly to the frontend without even touching the controller code. After 9 years of building backend systems, this is my biggest pet peeve. Your database schema and your API contract should never, ever be the same thing. The Senior Fix: Use Data Transfer Objects (DTOs). Yes, it feels like boilerplate. Yes, it feels tedious to map an OrderEntity to an OrderResponseDTO. But that separation is what saves you in production. 1. Security: You explicitly control exactly which fields leave your server. 2. Versioning: You can completely refactor your database schema without breaking the mobile app that relies on your API response. 3. Immutability: With modern Java, you can use Records for your DTOs. They are immutable, require zero Lombok boilerplate, and are incredibly fast. Your database represents how data is stored. Your API represents how data is consumed. Don't mix the two. What is your preferred way to map Entities to DTOs in Java? Do you write it manually, or do you use a library like MapStruct? Let's debate below. 👇 #CleanCode #Java #SpringBoot #SoftwareEngineering #BackendDevelopment #API #LLD #SystemDesign
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