Another day, another deep dive into backend fundamentals Today I explored something that looks simple at first but becomes really interesting as you go deeper — Optimistic Locking & Distributed Consistency Let me break it down the way I understood it 👇 • The Problem: Lost Updates Two users read the same data: User A → updates name to "Dominos Pizza" User B → updates name to "Dominos India" Without any protection: → Last write wins → One update is silently lost ,This is dangerous. • Optimistic Locking (Core Idea) Instead of locking the row , Allow multiple reads , Allow parallel updates But verify at write time using a version field: UPDATE ... WHERE id = ? AND version = ? If version changed → update fails If same → update succeeds ✅ 👉 No locks, no blocking, just conflict detection 🔹Important Insight Optimistic locking does NOT prevent conflict It detects conflict and forces a decision 🔹What happens on conflict? You decide: • Retry automatically • Ask user to resolve • Merge changes 🔹Role of @Version in JPA • Tracks version of each row • Automatically increments on update • Injects version condition in SQL • Throws exception if conflict detected 🔹 Now the real question: Distributed Systems What if we have one service and what if we have multiple databases? • Now things break • Each DB has its own version • No shared truth Conflicts go undetected 👉 Optimistic locking fails here 🔹 So what do real systems do? ✅ Primary + Read Replicas → Only one DB handles writes ✅ Sharding → Each record lives in exactly one DB #BackendEngineering #SystemDesign #Java #SpringBoot #DistributedSystems #OptimisticLocking #Microservices #LearningInPublic
Optimistic Locking & Distributed Consistency Explained
More Relevant Posts
-
Over the past few days, I’ve been diving deep into how JPA and Spring Data JPA handle database interactions — and honestly, understanding the internals changed how I look at backend systems. Here are 3 core building blocks that clicked for me: 🔹 DataSource The foundation that provides database connections (driver, URL, credentials). Without it, nothing talks to the database. 🔹 EntityManagerFactory A heavyweight, thread-safe factory that bootstraps JPA and creates EntityManager instances. Think of it as the control center of persistence. 🔹 EntityManager The workhorse that manages the persistence context, handles CRUD operations, and interacts with the database. Not thread-safe — so each transaction gets its own instance. Behind every @Transactional annotation, there’s a powerful orchestration happening: 🔹Transaction Manager ensures commit/rollback 🔹Persistence Context tracks entity states (new, managed, detached, removed) 🔹PlatformTransactionManager abstracts everything across technologies #Java #SpringBoot #JPA #BackendDevelopment #FullStackDeveloper #Microservices #SystemDesign #HappyLearning #DeveloperLife #SoftwareEngineering #Coding
To view or add a comment, sign in
-
-
I was building filtering for financial records in my backend. Date range. Category. Amount range. User scope. All optional. All combinable. I started with hardcoded query logic using if-else conditions for different filter cases. It got messy fast. Every new filter meant rewriting existing logic. At one point, the queries looked like they were never meant to be read again. So I scrapped it. I implemented the Specification pattern using Spring Data JPA. Each filter became an isolated, composable predicate. At runtime, only the active ones combine into a single query. No hardcoding. No duplication. Small change in approach. Big impact on scalability and future scope. Now, adding a new filter is just one addition. Existing logic doesn't change. This is the Open/Closed principle from SOLID in practice, open for extension, closed for modification. Each Specification also owns exactly one filter concern. Single Responsibility, naturally enforced. The filtering layer went from something I avoided touching to something I can extend confidently, without regression risk. Interesting how backend complexity shifts as systems grow: performance → security → maintainability. This was firmly the third. #Backend #Java #Maintainability #SOLID #LearningInPublic #SWE
To view or add a comment, sign in
-
☕ Understanding @Transactional in Spring Boot One annotation that quietly protects your data integrity: @Transactional It ensures multiple DB operations either: ✅ All succeed ❌ Or all rollback No partial data corruption. 🔍 Real Example @Transactional public void transferMoney(Account a, Account b, int amount) { withdraw(a, amount); deposit(b, amount); } If deposit fails → Spring rolls back withdraw automatically. 🧩 What Happens Under the Hood Spring creates a proxy around the method: 1️⃣ Start transaction 2️⃣ Execute method 3️⃣ Commit if success 4️⃣ Rollback if exception 🚨 Critical Rules Many Developers Miss • Works only on public methods • Works only on Spring-managed beans • Self-invocation bypasses transaction • RuntimeException triggers rollback by default 🧠 Production Insight Transactions define system consistency boundaries. Too large → locks & slow DB Too small → inconsistent state 💡 Best Practice Keep transactions: • Short • Focused • Database-only @Transactional is not just annotation magic — it’s a core reliability guarantee in backend systems. #SpringBoot #Java #BackendEngineering #Transactions #LearnInPublic
To view or add a comment, sign in
-
Day 14. My API worked perfectly. Until it hit 100 users. I had this: List<Order> orders = orderRepository.findAll(); for (Order order : orders) { System.out.println(order.getUser().getName()); } Because of queries I didn’t even know existed. Looks clean. It’s not. Here’s what was actually happening: → 1 query to fetch all orders → 1 query per order to fetch the user → 100 orders = 101 queries hitting your database That’s the N+1 problem. And it hides in plain sight. Your code looks clean. Your database is suffering. And you probably have this in your codebase right now. The fix is simple: Fetch what you need. In one query. @Query("SELECT o FROM Order o JOIN FETCH o.user") List<Order> findAllWithUser(); One query. One JOIN. Everything loaded together. What actually changes: → Performance — 101 queries becomes 1 → Scalability — works at 100 rows, breaks at 100,000 → Visibility — you won’t notice until production The hard truth: → ORMs make it easy to write slow code → Lazy loading is convenient until it isn’t → You need to know what SQL your code is generating Writing code that works is easy. Writing code that doesn’t silently destroy your database is the real skill. Are you logging your SQL queries in development? If not — you should be. 👇 Drop it below #SpringBoot #Java #Hibernate #BackendDevelopment #JavaDeveloper
To view or add a comment, sign in
-
Day 26. I stopped using @Data in my JPA entities. Not because it doesn't work. Because it was breaking things I didn’t understand. I used to write this: // ❌ Looks clean — hides real problems @Data @Entity public class User { @Id private Long id; @OneToMany(mappedBy = "user") private List<Order> orders; } Looks clean. Less code. Everything auto-generated. Until it didn’t. Here’s what actually happens: → toString() triggers lazy loading → Infinite recursion in bidirectional relationships → Unexpected database queries → Hard-to-debug logs That’s when it clicked. @Data is not made for entities. It generates: → equals() → hashCode() → toString() And those methods don’t play well with JPA proxies and relationships. So I changed it. (see implementation below 👇) What I learned: → Lombok is powerful — but not always safe → Entities are not simple POJOs → Generated methods can silently break your system The hard truth: → @Data works in tutorials → It fails in real systems → Most developers don’t notice until production Writing less code is easy. Writing safe code is what makes you a backend developer. Are you still using @Data in entities? 👇 #SpringBoot #Java #Hibernate #BackendDevelopment #CleanCode #JavaDeveloper
To view or add a comment, sign in
-
-
Optimizing for Milliseconds: Building a Custom Trie Search 🚀 As my logistics project, Vela Route, grows, I realized that standard database queries wasn't enough for the "search-as-you-type" experience I wanted. Today, I moved beyond CRUD and implemented a custom Trie (Prefix Tree) data structure in Java. 🧠 The Challenge: Database LIKE queries can get sluggish as records scale. 🛠️ The Solution: I built an in-memory Retrieval Tree that "warm-starts" via a Spring Boot CommandLineRunner. ⚡ The Result: Tracking number lookups now happen in $O(L)$ time (based only on the length of the string), making the search nearly instantaneous regardless of database size. It’s been an incredible deep dive into memory management, recursion, and bridging the gap between PostgreSQL and RAM. Check out the implementation on my GitHub! #Java #SpringBoot #DataStructures #SoftwareEngineering #VelaRoute #BackendDevelopment #Trie #CodingBootcamp #BuildingInPublic
To view or add a comment, sign in
-
-
🚨 I didn’t check every pair… and still got the maximum distance. Day 29 of my Backend Developer Journey — and today was about 👉 thinking smart instead of thinking more 🧠 LeetCode Breakthrough Solved “Two Farthest Houses with Different Colors” 💡 What clicked: → No need to compare all pairs → Just compare with first and last house → Expand from both ends ⚡ The real trick: 👉 The farthest distance will always involve either the first or the last element 🔍 Key Insight Instead of brute force (O(n²)): 👉 Use two pointers 👉 Compare edges only ⚡ Optimized to O(n) with simple logic 🔗 My Submission:https://lnkd.in/gE4cBmuV ☕ Spring Boot Learning 🔁 JPA Repository Revision Today I revisited the core of Spring Data JPA 👇 👉 JpaRepository simplifies database operations 👉 No need to write boilerplate SQL 👉 Built-in methods like: → save() → findById() → findAll() → delete() ⚡ Why this matters 💡 Strong fundamentals > New concepts 👉 Writing less code 👉 Getting more done 👉 Cleaner backend design 🧠 The Shift 👉 Optimization is about observing patterns 👉 Revising basics makes concepts stronger 👉 Backend mastery = consistency + clarity 📘 Spring Boot Notes:https://lnkd.in/gpWQvkyK 📈 Day 29 Progress: ✅ Improved problem-solving efficiency ✅ Strengthened JPA fundamentals ✅ Practicing consistency daily 💬 Have you ever solved a problem faster by doing less work? 😄 #100DaysOfCode #BackendDevelopment #SpringBoot #Java #LeetCode #CodingJourney
To view or add a comment, sign in
-
-
🚀 DSL vs @Query in Spring Data JPA While working with Spring Data JPA, I learned that by default it provides methods to work with the primary key like findById(). But what if we want to fetch data using other fields like name, age, etc.? 🤔 We have two approaches 👇 🔹 1. Domain-Specific Language (DSL) List<User> findByName(String name); ✔️ Method Naming Convention ✔️ Query is automatically generated ✔️ Easy to write and read ✔️ Best for simple queries 🔹 2. @Query Annotation @Query("SELECT u FROM User u WHERE u.name = :name") List<User> getUserByName(String name); ✔️ Query is written manually (JPQL/SQL) ✔️ More flexibility ✔️ Best for complex queries (joins, multiple conditions) 💡 Key Difference: DSL → Simple & automatic @Query → Flexible & customizable 🎯 Conclusion: Use DSL for quick and simple queries, and switch to @Query when you need more control. #Java #SpringBoot #SpringDataJPA #BackendDevelopment #Coding #Developers #Learning
To view or add a comment, sign in
-
-
What I learned today while exploring Spring Boot. Instead of just going through theory, I focused on understanding how Controllers actually work in a real backend application. Here’s what I covered: 🔹 @RestController — used to expose REST APIs and return data directly (JSON/XML) 🔹 @Controller — mainly used for returning views (like in MVC-based applications) 🔹 Mapping requests properly using: → @RequestMapping (base mapping) → @GetMapping (fetch data) → @PostMapping (create data) → @PutMapping (update data) → @DeleteMapping (delete data) → @PatchMapping (partial update) 🔹 Handling client input: → @PathVariable for dynamic values in URL → @RequestParam for query parameters → @RequestBody for sending JSON data What I’m realizing is — Controllers are not just annotations, they define how the client and backend communicate. Focusing more on clarity and real usage rather than just memorizing. Learning step by step ⚡ #SpringBoot #Java #RestAPI #LearningJourney #Consistency #LearningJourney #Consistency
To view or add a comment, sign in
-
Most developers equate slow APIs with bad code. However, the issue often lies elsewhere. Consider this scenario: You have a query that appears perfectly fine: SELECT o.id, c.name FROM orders o JOIN customers c ON o.customer_id = c.id Yet, the API is painfully slow. Upon checking the execution plan, you find: NESTED LOOP → TABLE ACCESS FULL ORDERS → INDEX SCAN CUSTOMERS At first glance, this seems acceptable. But here's the reality: for each row in orders, the database is scanning and filtering again. If orders contain 1 million rows, that's 1 million loops. The real issue wasn’t the JOIN; it was the database's execution method. After adding an index: CREATE INDEX idx_orders_date ON orders(created_at); The execution plan changed to: INDEX RANGE SCAN ORDERS → INDEX SCAN CUSTOMERS As a result, query time dropped significantly. Key lessons learned include: • Nested Loop is efficient only when: → the outer table is small → the inner table is indexed • Hash Join is preferable when: → both tables are large → there are no useful indexes • Common performance issues stem from: → full table scans → incorrect join order → missing indexes → outdated statistics A common mistake is this Java code: for (Order o : orders) { o.getCustomer(); } This essentially creates a nested loop at the application level (N+1 query problem). Final takeaway: Don’t just write queries; understand how the database executes them. That's where true performance improvements occur. If you've resolved a slow query using execution plans, sharing your experience would be valuable. #BackendDevelopment #DatabaseOptimization #SQLPerformance #QueryOptimization #SystemDesign #SoftwareEngineering #Java #SpringBoot #APIPerformance #TechLearning #Developers #Coding #PerformanceTuning #Scalability #DistributedSystems #DataEngineering #Debugging #TechTips #LearnInPublic #EngineeringLife
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