The @TransactionalEventListener Trap (Why you are sending emails for failed transactions) 📧 🛑 We sent the customer an "Order Confirmed" email, but the Database rolled back the transaction. Here is the silent danger of Spring Application Events. 💥 Headline: Are you using @EventListener in Spring Boot to decouple your business logic? You are actively building a Data Inconsistency trap. Let's talk Architecture. 🧠 Hey LinkedInFamily, In Backend System Design, decoupling our code using Event-Driven Architecture is a best practice. Instead of making the OrderService send emails directly, it simply fires an OrderCreatedEvent, and a separate NotificationService handles the rest. I recently audited an E-commerce microservice where customers were complaining. They received "Order Confirmed" emails and SMS messages, but when they checked their accounts, the orders didn't exist! We checked the logs. The OrderService fired the event successfully, but a microsecond later, the Database threw a ConstraintViolationException and rolled back the transaction. The database did its job. But the email had already left the server. You cannot rollback an email. The culprit? A fundamental misunderstanding of the Spring Event Lifecycle. The Junior Mistake (The Premature Event Trap): The developer used a standard event listener inside a transactional boundary. The Architect's Architecture (@TransactionalEventListener): We NEVER trigger irreversible external actions (like sending emails, charging cards, or calling 3rd-party APIs) until the database mathematically guarantees the data is saved. We replace the standard listener with a @TransactionalEventListener and set the phase to AFTER_COMMIT. This tells Spring: "Hold this event in memory. Only execute this listener IF and WHEN the database transaction is successfully committed!" 🛡 My Engineering Takeaway In distributed systems, an action isn't real until the database says it's real. Don't celebrate the victory before the referee blows the final whistle. Wait for the commit. Then send the email. 🛠️✨ Ujjwal Kumar || Java Software Engineer @ PrernaGati & Technology || Freelance Full Stack Developer System Design | Java | C++ | DSA #Java #SpringBoot #SystemDesign #DatabaseArchitecture #Microservices #BackendDevelopment #SoftwareEngineering #TechLeadership #EventDrivenArchitecture #CleanCode
The TransactionalEventListener Trap: Avoid Sending Emails Before Database Commit
More Relevant Posts
-
Frontend says: “I send requests.” Database says: “I store data.” API Gateway says: “I route requests.” Backend developer? 👉 “I connect everything.” Behind every smooth application is a backend handling far more than just APIs. 🔧 What backend actually does: • Designs and exposes APIs • Manages database interactions • Implements business logic • Handles authentication & authorization • Ensures security and validation • Manages deployment & scalability It’s the layer where everything comes together. 💡 Reality check: Frontend gets the visuals. Database stores the data. But backend is the brain of the system. 🚀 Senior mindset: Don’t just write APIs. Understand system design, data flow, and scalability. Think about how each component communicates and fails. Because in real-world systems… If backend breaks, everything breaks. #BackendDevelopment #Java #SpringBoot #API #SystemDesign #SoftwareEngineering #Developers #Coding
To view or add a comment, sign in
-
-
In backend systems, especially when building scalable and maintainable services, we often face a common challenge: 👉 How do we add new functionality to an object without modifying its existing code? This is where the Decorator Pattern comes into play. 🔍 What is the Decorator Pattern? The Decorator Pattern is a structural design pattern that allows you to dynamically add behavior to an object at runtime, without altering its original structure. Instead of modifying a class directly or creating endless subclasses, we "wrap" the object with additional functionality. 🧠 Why it matters in backend development? As a Java backend developer, you frequently deal with: Logging Security checks (authentication/authorization) Caching Monitoring Data transformation Now imagine hardcoding all of these into your core business logic 😬 That leads to: ❌ Tight coupling ❌ Hard-to-maintain code ❌ Violations of SOLID principles The Decorator Pattern helps you: ✅ Keep core logic clean ✅ Add features independently ✅ Follow Open/Closed Principle (open for extension, closed for modification) ⚙️ Real-world backend analogy Think of a basic API service that processes requests. Now, instead of modifying it directly, you can "decorate" it with: 🔐 Authentication layer 📊 Logging layer ⚡ Caching layer Each layer wraps the original service and adds its behavior — without touching the core implementation. 💡Key Idea “Wrap, don’t modify.” You build functionality like layers around an object, and each layer enhances behavior independently. 🧩 When should you use it? Use the Decorator Pattern when: You need flexible feature addition You want to avoid class explosion (too many subclasses) You care about clean architecture & separation of concerns Check it out - https://lnkd.in/gbfy8mAq #Java #BackendDevelopment #DesignPatterns #SystemDesign #CleanCode #SoftwareEngineering
To view or add a comment, sign in
-
-
The Infinite Wait Trap (Why a slow 3rd-party API is crashing your entire server) ⏳ 🛑 A 3rd-party Payment API became slow, and it crashed our entire E-commerce Microservice. Here is the silent danger of Cascading Failures. 💥 Headline: Are you making HTTP calls to external APIs using a default RestTemplate or WebClient? You are actively leaving your application wide open to Thread Pool Exhaustion. Let's talk Architecture. 🧠 Hey LinkedInFamily, In Backend System Design, we don't just engineer for when things fail completely (like a 500 Bad Request). We must engineer for something much more dangerous: when things get extremely slow. I recently audited an Order Microservice. It relied on a 3rd-party Shipping API to calculate delivery costs. One day, the Shipping API degraded. It didn't throw an error; it just started taking 60 seconds to respond instead of 100 milliseconds. Within 2 minutes, our entire Order Microservice became completely unresponsive. Even the /health endpoint went down. The CPU was fine. The Database was fine. The culprit? We trusted the framework's default HTTP client configuration. The Junior Mistake (The Infinite Wait Trap): The developer instantiated a default REST client without configuring strict boundaries. The Architect's Architecture (Strict Timeouts & Fail-Fasts): We NEVER trust the network. We NEVER trust external services. We must forcefully cut the wire if a service doesn't respond within a strict Service Level Agreement (SLA). We use a RestTemplateBuilder to explicitly define both a Connect Timeout (time to establish a TCP handshake) and a Read Timeout (time to wait for the actual data). 🛡 My Engineering Takeaway In microservices architecture, hope is not a strategy. You cannot control how fast external services reply, but you can absolutely control how long you are willing to wait. Don't let a slow neighbor trap you in the hallway. Set a timer and walk away. 🛠️✨ Ujjwal Kumar || Java Software Engineer @ PrernaGati & Technology || Freelance Full Stack Developer System Design | Java | C++ | DSA #Java #SpringBoot #SystemDesign #Microservices #CloudArchitecture #BackendDevelopment #SoftwareEngineering #TechLeadership #PerformanceOptimization #Resilience
To view or add a comment, sign in
-
-
Lately I’ve been seeing a pattern while working on enterprise apps. Developers from strong .NET / Java backgrounds feeling a bit "off" in newer setups. Not because of coding. More because of how the work is structured now. In a typical flow today, you’re not just writing a service and exposing an API. You’re dealing with things like: • multiple systems reading/writing the same data • async flows (queues, events, delayed updates) • APIs you don’t control • workflows defined outside your code • business rules changing mid-implementation So even if your service is correct… the system behavior might not be. That’s where it starts feeling different. Also noticing more cases where: part of the logic sits in backend services part in workflow tools / low-code part defined directly with business users Which leads to something like this: The real shift isn’t just technical. It’s how systems are shaped. From: “developer builds system” To: “developer + business collaboratively shape system” You’re no longer only responsible for logic. You’re responsible for how everything behaves together. Put together a deeper breakdown here: https://lnkd.in/dtE96nj3 #SoftwareEngineering #DistributedSystems #SystemDesign #APIs #LowCode #Microservices
To view or add a comment, sign in
-
-
As backend developers, we often deal with complex objects — multiple fields, optional parameters, and different configurations. Writing clean, maintainable, and scalable code in such scenarios can get tricky. That’s where the Builder Design Pattern shines. 💡 Instead of creating objects using large constructors or messy setters, the Builder pattern allows us to construct objects step-by-step — making the code more readable and flexible. 🔹 Why use Builder Pattern? Avoids telescoping constructor problem Improves code readability Handles optional parameters gracefully Encourages immutability Makes object creation more controlled and expressive 🔹 Where I find it useful (real backend scenarios): Creating complex DTOs or API request/response objects Building configuration objects (DB configs, service configs) Constructing domain models with many optional fields Writing test data builders for clean test cases 🔹 Quick Example : Instead of: new User("Aritra", "aritra@mail.com", "123", null, null, true); We write: User user = User.builder() .name("Aritra") .email("aritra@mail.com") .phone("123") .isActive(true) .build(); Much cleaner. Much safer. Much scalable. 💭 Key Insight: Builder pattern is not just about avoiding constructor chaos — it's about designing code that scales with complexity. If you're working in backend systems (especially with Java, Spring Boot, or microservices), mastering this pattern will level up your design skills significantly. Check it out - https://lnkd.in/gUmCUB_u #BackendDevelopment #Java #SystemDesign #DesignPatterns #CleanCode #SoftwareEngineering
To view or add a comment, sign in
-
-
Last week a junior dev asked me this in a code review: "Why do you always use Long instead of long for IDs?" 10 minutes earlier — I'd probably have said: "Habit. It's just better." But that's a garbage answer. So I actually stopped and thought about it. Here's what I came up with 👇 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ❌ long id; (primitive) → Default value: 0 → Cannot be null → Database NULL? Boom. NullPointerException at unboxing time. → "Is this ID missing or is it genuinely zero?" You can't tell. ✅ Long id; (wrapper) → Default value: null → Can distinguish "not set" from "zero" → Works seamlessly with Spring Data JPA, Jackson, Optional, database NULLs → The 10-byte object overhead is irrelevant in 99.9% of real apps ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ The same logic applies to: → Integer over int (for nullable fields) → Boolean over boolean (for "not answered" states) → BigDecimal over double (for money — ALWAYS) The "use primitives for performance" advice made sense in 2005. In 2026, with Spring Boot apps running on containers with 2GB RAM? Clarity > micro-optimization. Every. Single. Time. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Which Java "obvious habit" did YOU realize was actually wrong after 1-2 years of real work? Drop it below 👇 #Java #SpringBoot #CleanCode #BackendDeveloper #SoftwareEngineering
To view or add a comment, sign in
-
-
🚀 Built a Custom Rate Limiter Middleware in Node.js & Express Today I implemented a Rate Limiting system from scratch to understand how APIs protect themselves from excessive or malicious requests. Instead of using libraries, I focused on the core logic, data flow, and middleware structure to strengthen my backend fundamentals. 💡 What this project demonstrates How APIs control request frequency Middleware architecture in Express Handling IP-based request tracking Config-driven scalable structure Clean folder architecture for production-ready apps 📂 Project Structure src ┣ config → rateLimitConfig.js ┣ middleware → rateLimitMiddleware.js ┣ routes → testRoutes.js ┣ utils → store.js ┗ app.js server.js ⚙️ Key Concepts Implemented • IP based request tracking • Configurable request window • Map-based in-memory store • Middleware chaining • Clean separation of concerns • Scalable folder structure 🧠 Logic Overview Each request stores the IP with: request count start timestamp If the number of requests exceeds the defined limit within the time window → API returns 429 Too Many Requests This helps prevent: ✔ API abuse ✔ Brute force attempts ✔ Server overload ✔ DDoS-like patterns (basic protection layer) 📊 Config Example Time Window → 1 minute Max Requests → 5 per IP 🔧 Tech Used Node.js | Express.js | Middleware | REST API | ES Modules Small project, but very important concept for building scalable and production-ready backend systems. Next step → Redis based distributed rate limiting 🔥 #NodeJS #ExpressJS #BackendDevelopment #WebDevelopment #APIDesign #SoftwareEngineering #FullStackDeveloper #JavaScript #CodingJourney #100DaysOfCode #Developers #Tech #Programming #LearnInPublic #BuildInPublic #ScalableSystems #SystemDesign #Coding #OpenToWork #FresherJobs #BackendEngineer
To view or add a comment, sign in
-
-
إزاي الـ Request بيمشي جوه الـ Back-end؟ لما المستخدم يطلب حاجة من التطبيق (زي تسجيل الدخول)، بيحصل الآتي: 1️⃣ الـ Request بيبعت من الـ Client (الموبايل أو المتصفح) 2️⃣ يوصل للـ Controller في السيرفر 3️⃣ الـ Controller يمرره للـ Service (هنا بيكون المنطق الأساسي) 4️⃣ الـ Service تتعامل مع الـ Database 5️⃣ يرجع Response للمستخدم الترتيب ده هو أساس أي تطبيق معمول بـ Java باستخدام Spring Boot كل ما تفهم الـ Flow ده كويس… هتعرف تكتب كود أنضف وتفهم السيستم بشكل أفضل How does a request flow inside the Back-end? When a user sends a request (like logging in), this is what happens: 1️⃣ The request is sent from the client (browser or mobile) 2️⃣ It reaches the Controller on the server 3️⃣ The Controller passes it to the Service (business logic) 4️⃣ The Service interacts with the Database 5️⃣ A response is sent back to the user This flow is the foundation of most Java applications built with Spring Boot The better you understand this flow… the better you’ll write clean code and understand systems #EraaSoft EraaSoft #Java #BackendDevelopment #SpringBoot #SoftwareArchitecture #RESTAPI #Programming #Coding #Tech #Developer #SystemDesign
To view or add a comment, sign in
-
🚀 𝗨𝗻𝗱𝗲𝗿𝘀𝘁𝗮𝗻𝗱𝗶𝗻𝗴 𝟯-𝗧𝗶𝗲𝗿 𝗔𝗿𝗰𝗵𝗶𝘁𝗲𝗰𝘁𝘂𝗿𝗲 – 𝗔 𝗖𝗼𝗺𝗽𝗹𝗲𝘁𝗲 𝗢𝘃𝗲𝗿𝘃𝗶𝗲𝘄 In today’s modern application development, structuring systems efficiently is the key to scalability, performance, and maintainability. One of the most widely used approaches is the **𝟯-𝗧𝗶𝗲𝗿 𝗔𝗿𝗰𝗵𝗶𝘁𝗲𝗰𝘁𝘂𝗿𝗲**. 🔹 **𝗪𝗵𝗮𝘁 𝗶𝘀 𝗶𝘁?** 3-Tier Architecture divides an application into three layers: 1️⃣ **𝗙𝗿𝗼𝗻𝘁𝗲𝗻𝗱 (𝗣𝗿𝗲𝘀𝗲𝗻𝘁𝗮𝘁𝗶𝗼𝗻 𝗟𝗮𝘆𝗲𝗿)** – User interface (HTML, CSS, JavaScript, React, Angular) 2️⃣ **𝗕𝗮𝗰𝗸𝗲𝗻𝗱 (𝗔𝗽𝗽𝗹𝗶𝗰𝗮𝘁𝗶𝗼𝗻 𝗟𝗮𝘆𝗲𝗿)** – Business logic (Java, Python, .NET, Node.js) 3️⃣ **𝗗𝗮𝘁𝗮𝗯𝗮𝘀𝗲 (𝗗𝗮𝘁𝗮 𝗟𝗮𝘆𝗲𝗿)** – Data storage (MySQL, PostgreSQL, MongoDB) 🔹 **𝗪𝗵𝘆 𝗶𝘁 𝗺𝗮𝘁𝘁𝗲𝗿𝘀?** ✔ Better scalability ✔ Improved security ✔ Easy maintenance ✔ Separation of concerns 🔹 **𝗘𝘃𝗼𝗹𝘂𝘁𝗶𝗼𝗻 𝗼𝗳 𝗔𝗿𝗰𝗵𝗶𝘁𝗲𝗰𝘁𝘂𝗿𝗲:** ➡ 1-Tier: All components in one place ➡ 2-Tier: Frontend + Backend connected to Database ➡ 3-Tier: Fully separated layers for flexibility and efficiency 🔹 **𝗥𝗼𝗹𝗲 𝗼𝗳 𝗗𝗲𝘃𝗢𝗽𝘀:** Once the code is written by developers, **𝗗𝗲𝘃𝗢𝗽𝘀 𝗘𝗻𝗴𝗶𝗻𝗲𝗲𝗿𝘀** ensure smooth deployment, integration, and delivery using tools and automation. 💡 This architecture is the backbone of most modern web and enterprise applications. learning with DevOps Insiders Aman Gupta Ashish Kumar #DevOps #SoftwareArchitecture #WebDevelopment #3TierArchitecture #Frontend #Backend #Database #LearningJourney
To view or add a comment, sign in
-
-
Don’t call yourself a Backend Developer… if all you do is CRUD. A reality check I learned with experience 👇 At the start, I thought backend development was simple: • Create APIs • Connect database • Return data And yes… I could build that. But real projects changed everything. I had to: • Handle complex business logic • Design scalable systems • Secure APIs and manage authentication • Optimize performance and queries • Handle errors, edge cases, and failures • Integrate third-party services (payments, notifications, etc.) That’s when it hit me: 👉 Writing CRUD APIs ≠ Real Backend Development Real backend development starts when you: ✔ Think about scalability ✔ Design proper architecture ✔ Handle real-world edge cases ✔ Ensure security and performance ✔ Solve business problems, not just return data T Today, I focus on building backend systems that actually support real applications — not just endpoints. 💡 My message to developers: Don’t stop at CRUD. Learn: • System design • Security • Performance optimization • Real-world problem solving That’s what makes you a real backend developer. For more information follow: Hamza Rehman Chohan #BackendDevelopment #dotnet #API #SoftwareEngineering #Programming #FullStackDeveloper #TechGrowth
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