Excited to share a project I have been working on — FinFlow, a production-inspired banking backend built with Java and Spring Boot. The goal was simple: go beyond tutorial-level projects and build something that reflects real backend engineering challenges. What FinFlow covers: 🔐 JWT Authentication — stateless session management, BCrypt password encoding, and a custom Spring Security filter chain 💸 Money Transfers — idempotency via Redis key tracking, deadlock-safe pessimistic locking with ordered lock acquisition, and atomic balance updates 📨 Event-driven Fraud Detection — Kafka-based async pipeline with a dedicated thread pool, performing high-frequency, odd-hour, and card-testing checks without impacting transaction response time ⚙️ Batch Processing — asynchronous job execution using CompletableFuture with Redisson distributed locking to prevent duplicate processing 🛡️ Resilience — Resilience4j circuit breakers with a Facade pattern, and distributed rate limiting using Bucket4j backed by Redis 🧪 Unit Testing — JUnit 5 and Mockito covering success and failure paths of core transaction logic A few challenges worth mentioning: 🔄 Resolved a circular dependency between SecurityConfig and UserService by extracting PasswordEncoder to a separate configuration class — a good reminder that Spring's bean lifecycle requires deliberate design 🔒 Prevented deadlocks in concurrent transfers by enforcing ordered lock acquisition — always locking the lower account ID first regardless of transfer direction, making a circular wait impossible Every design decision in this project has a deliberate justification — from choosing Redisson over raw Redis for locking, to using a Facade layer to separate resilience concerns from business logic. The repository is available on GitHub — feel free to explore: https://lnkd.in/gRisUBED #Java #SpringBoot #BackendDevelopment #OpenToWork #SpringSecurity #Kafka #Redis #SystemDesign
Java Spring Boot Banking Backend FinFlow Project
More Relevant Posts
-
Started Day 2 on my offline-first UPI payment system in Java + Spring Boot. Today’s focus was moving beyond basic money transfer APIs into something real products need: transaction history. Built a recent transactions endpoint that returns the last activity for a user instead of dumping raw database rows. Also started shaping responses through DTO mapping so customers only see relevant data like amount, status, counterparty, and transaction type (Sent / Received) — not internal fields. One underrated part of backend development: debugging response serialization, mapping layers, and edge cases often takes more effort than writing the endpoint itself. That’s where real learning happens. Current progress: ✅ Account creation API ✅ Payment transfer API ✅ Custom exception handling ✅ Transaction history feature in progress ✅ DTO-based response design Next steps: Finish transaction history cleanly Add timestamps JWT auth layer Idempotency for duplicate payment prevention PostgreSQL migration from H2 Building with a product mindset, not just CRUD. #Java #SpringBoot #BackendDevelopment #SystemDesign #FinTech #BuildInPublic #backenddev #SpringAI #SpringdataJPA #microservices
To view or add a comment, sign in
-
Started building an offline-first UPI payment system in Java + Spring Boot. The core problem: digital payments fail when internet drops. Most solutions assume connectivity. This one doesn't. Day 1 focused on foundations- Account and Transaction models, initial settlement logic, REST APIs for testing, and H2 for rapid prototyping (PostgreSQL planned next for persistent storage and scale). But the more interesting work was defining the real engineering challenges: • How do you prevent the same payment from being processed twice when multiple relay devices forward it simultaneously? • How do you ensure an intercepted payment packet from yesterday cannot be replayed today? • How do you route payment data through untrusted devices without those devices being able to read it? None of that is implemented yet. But clear problem definition is exactly how Day 1 should end. #Java #SpringBoot #SystemDesign #FinTech #BuildInPublic #coding #springai
To view or add a comment, sign in
-
Java 21 is generating buzz around Virtual Threads, but the crucial features ensuring their safety in production are often overlooked. After over a decade in Banking and Retail, I've learned that "Scalability" without "Predictability" can lead to 3 AM incidents. While many focus on the hype of "million threads," here are three essential features in Java 21 that truly matter for your Spring Boot 3 services: 1. Scoped Values (The ThreadLocal Killer): ThreadLocal was effective in a world with 200 threads, but with 1 million Virtual Threads, it can lead to memory leaks. Scoped Values enable the sharing of immutable data across threads, such as user context in banking transactions, without memory bloat and with total thread safety. It serves as the implicit method parameter we've needed. 2. Sequenced Collections (The API we should have had in 1995): If you've ever had to write list.get(list.size() - 1) or struggled with a LinkedHashMap to find the last entry, you'll appreciate this. SequencedCollection, SequencedSet, and SequencedMap introduce uniform .getFirst() and .getLast() methods, significantly reducing the risk of "off-by-one" errors in complex data processing pipelines. 3. Record Patterns & Exhaustive Switch: If you're still using instanceof and manual casting, it's time to upgrade. Deconstructing a Record directly in a switch statement (Record Patterns) revolutionizes Fintech applications. You can match, validate, and extract fields from a Transaction record in a single clean block, eliminating the "Null Check" soup. The key takeaway: Don't just update the JDK version in your pom.xml. Replace your ThreadLocals with ScopedValues and your manual deconstruction with Record Patterns. That's where the real performance gains for 2026 lie. To my fellow Java Seniors: Which of these features are you currently using in your PRs? Or are we still just "testing #Java #Java21 #SpringBoot #BackendEngineering #SoftwareArchitecture #CleanCode #FullStackDeveloper #Microservices #SystemDesign #JavaDeveloper #SeniorDeveloper #H1BTech #ProjectLoom #TechTrends2026
To view or add a comment, sign in
-
🔐 Optimistic vs Pessimistic Locking - When to Use What? Concurrency control is a critical part of building reliable systems, especially in high-traffic, distributed applications. Two common strategies are optimistic locking and pessimistic locking each with its own trade-offs. 👉 Optimistic Locking Assumes conflicts are rare. Instead of locking data upfront, it allows multiple transactions to proceed and checks for conflicts before committing (usually via a version or timestamp). ✔️ High performance & scalability ✔️ No blocking of reads/writes ❗ Requires retry logic on conflict 👉 Pessimistic Locking Assumes conflicts are likely. It locks the data at the start of a transaction to prevent others from modifying it. ✔️ Strong consistency ✔️ No retry overhead ❗ Can cause blocking, deadlocks, and reduced throughput 💡 When to use what? Use optimistic locking in high-read, low-conflict systems (e.g., microservices, REST APIs) Use pessimistic locking when data integrity is critical and conflicts are frequent (e.g., financial transactions) 🚀 In modern cloud-native systems, optimistic locking is often preferred due to better scalability—but the right choice always depends on your use case. #SoftwareEngineering #Java #SpringBoot #Microservices #SystemDesign #BackendDevelopment
To view or add a comment, sign in
-
-
📜 𝗜𝗺𝗽𝗿𝗼𝘃𝗶𝗻𝗴 𝗟𝗼𝗴𝗴𝗶𝗻𝗴 𝘄𝗶𝘁𝗵 @𝗟𝗼𝗴 / @𝗦𝗹𝗳𝟰𝗷 𝗶𝗻 𝗦𝗽𝗿𝗶𝗻𝗴 𝗕𝗼𝗼𝘁 𝗔𝗽𝗽𝗹𝗶𝗰𝗮𝘁𝗶𝗼𝗻𝘀 🪶 Effective logging is essential for monitoring, troubleshooting, and maintaining Spring Boot applications. Well-structured logs provide visibility into application behavior and help teams diagnose issues faster. @Log and @Slf4j, provided by Lombok, make logging simpler and more consistent across your codebase. 𝗪𝗵𝗮𝘁 𝗔𝗿𝗲 @𝗟𝗼𝗴 𝗮𝗻𝗱 @𝗦𝗹𝗳𝟰𝗷? @Log and @Slf4j are Lombok annotations that automatically generate logger instances for your classes. Instead of manually creating logger objects, developers can rely on these annotations to reduce boilerplate code and keep classes clean and readable. 𝗣𝘂𝗿𝗽𝗼𝘀𝗲 The main purpose of using @Log and @Slf4j is to standardize and simplify logging while ensuring high performance and clarity. They help developers focus on meaningful log messages rather than repetitive setup code. 𝗧𝘄𝗼 𝗞𝗲𝘆 𝗙𝗲𝗮𝘁𝘂𝗿𝗲𝘀 𝘙𝘦𝘥𝘶𝘤𝘦𝘥 𝘉𝘰𝘪𝘭𝘦𝘳𝘱𝘭𝘢𝘵𝘦 𝘊𝘰𝘥𝘦 – Loggers are automatically generated, making classes cleaner and easier to maintain. 𝘍𝘭𝘦𝘹𝘪𝘣𝘭𝘦 𝘓𝘰𝘨𝘨𝘪𝘯𝘨 𝘓𝘦𝘷𝘦𝘭𝘴 – Support for common log levels like DEBUG, INFO, WARN, and ERROR, allowing better control over application observability. 𝗛𝗼𝘄 𝗜𝘁 𝗪𝗼𝗿𝗸𝘀 When you annotate a class with @Slf4j (or @Log), Lombok generates a static logger field at compile time. This logger integrates seamlessly with logging frameworks such as Logback or Log4j2, which are commonly used in Spring Boot applications. 𝗪𝗵𝗲𝗻 𝗦𝗵𝗼𝘂𝗹𝗱 𝗬𝗼𝘂 𝗨𝘀𝗲 𝗜𝘁? @Log and @Slf4j are ideal for any Spring Boot application that requires structured, consistent logs—especially in microservices, where logs play a key role in monitoring and debugging distributed systems. #Java #SpringBoot #Logging #Lombok #Slf4j #Observability #SoftwareEngineering #TechTalk #spring #react #next #pix #banking #bank #payment #fullstack #fintech #trading #finance #FinanceialInfrastructure #realTime #fedNow #Microservices #DistributedSystems #Architecture #EventDriven #SystemDesign #TechTalk #SoftwareEngineering
To view or add a comment, sign in
-
-
Day 6 — The Race Condition Bug Nobody talks about this in backend systems… Everything works perfectly… Until two users hit the same API at the same time. And suddenly: • Duplicate orders • Negative stock • Payment processed twice No errors. No crashes. Just silent data corruption. ⸻ 💥 The Problem Two threads access and modify shared data at the same time without proper control. Example: if (stock > 0) { stock–; } Looks correct, right? But under concurrency: Thread A reads stock = 1 Thread B reads stock = 1 Both decrement 👉 Final stock = -1 ⸻ ⚠️ Why it’s dangerous • Hard to reproduce (only happens under load) • Works fine in local testing • Fails silently in production • Direct impact on money and trust ⸻ ✅ The Fix Use proper concurrency control: • Optimistic locking (@Version) • Pessimistic locking (DB level) • Atomic operations • Synchronized blocks / locks • Idempotency for critical APIs ⸻ 🧠 Real lesson If your system handles payments, orders, or inventory… You’re already exposed to race conditions. It’s not “if” it will happen. It’s “when”. ⸻ 👇 Have you ever faced a race condition in production? What was your fix? ⸻ #Backend #Java #Microservices #SystemDesign #Concurrency #SpringBoot #CodingBugs #TechLeadership
To view or add a comment, sign in
-
-
🚀 Understanding @Transactional in Spring Boot If you're working with Spring Boot, one annotation you must understand deeply is @Transactional. It plays a critical role in ensuring data consistency and integrity in your application. 🔹 What is @Transactional? @Transactional is used to manage database transactions in Spring. It ensures that a group of operations either: ✔️ All succeed (COMMIT) ❌ Or all fail together (ROLLBACK) 🔹 Why is it important? Imagine transferring money between two accounts: Debit from Account A Credit to Account B If one step fails and the other succeeds, your data becomes inconsistent. @Transactional prevents this by treating both steps as a single unit. 🔹 Key Features: ✅ Automatic transaction management ✅ Rollback on runtime exceptions ✅ Supports propagation (REQUIRED, REQUIRES_NEW, etc.) ✅ Supports isolation levels (READ_COMMITTED, SERIALIZABLE, etc.) 🔹 Example: @Service public class PaymentService { @Transactional public void transferMoney() { debit(); credit(); } } If any method fails, the entire transaction is rolled back. 🔹 Important Notes: ⚠️ Works only on public methods ⚠️ Self-invocation doesn’t trigger transactions ⚠️ By default, only unchecked exceptions cause rollback 🔹 Pro Tip: Use @Transactional at the service layer, not the controller layer, to maintain clean architecture. 💡 Mastering transactions is key to building reliable and scalable backend systems. #SpringBoot #Java #BackendDevelopment #Transactions #SoftwareEngineering #Fintech
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
-
Day 8 — The Idempotency Bug User clicks “Pay”… nothing happens… clicks again. And suddenly — 💸 Payment deducted twice. ⸻ The Setup public void processPayment(PaymentRequest request) { paymentGateway.charge(request); orderService.markAsPaid(request.getOrderId()); } Looks correct. Works perfectly in testing. ⸻ The Problem In real-world systems: • Network retries • Client timeouts • Double clicks • Gateway retry mechanisms 👉 Same request gets processed multiple times Result: ❌ Duplicate payments ❌ Duplicate orders ❌ Broken trust ⸻ ✅ The Fix: Idempotency Key Every request must be uniquely identifiable. if (paymentRepository.existsByIdempotencyKey(request.getKey())) { return; // already processed } paymentGateway.charge(request); paymentRepository.save(request.getKey()); 🔥 Production-Grade Approach • Generate Idempotency-Key (UUID) per request • Store with status (PENDING / SUCCESS / FAILED) • Add unique constraint in DB • Return same response for repeated requests • Use Redis for fast lookup (optional) ⸻ 🧠 Senior Insight Idempotency is not just backend logic. It’s a contract between client + server. ⸻ 🎯 The Lesson Retries are unavoidable in distributed systems. Duplicate execution is not. ⸻ If your system handles payments, orders, inventory… 👉 Idempotency is a MUST. ⸻ #BackendDevelopment #Java #SpringBoot #Microservices #SystemDesign #Fintech #DistributedSystems #APIDesign
To view or add a comment, sign in
-
-
Day 3 of Building an Offline UPI Payment System with Spring Boot Today I implemented idempotency in the payment flow using a unique requestId, while also studying the importance of concurrency handling in payment systems. What was added: • Duplicate payment requests are detected and blocked • Prevents double debit during retries or network interruptions • Proper 409 CONFLICT response handling • Custom exception flow for cleaner API behavior • Initial understanding of how concurrent duplicate requests can impact transactions Why this matters: In payment systems, retries and simultaneous requests are common. Without idempotency and concurrency safeguards, the same transaction can be processed multiple times. Current implementation works, but there is room to improve: Areas of improvement: • Return the original transaction response instead of only throwing duplicate error • Strengthen concurrent request handling with DB constraints / locking strategies • Add request payload validation for reused requestId • Introduce expiry/cleanup strategy for old idempotency keys • Improve observability with logs and audit trails Next step: I’ll be upgrading this into a more production-ready payment flow by improving concurrency safety and returning previous transaction state on retries. Built with: -Spring Boot -Spring Data JPA -H2 -REST APIs -Java Reliable backend systems are built by handling retries, race conditions, and edge cases not just successful requests. #Java #SpringBoot #BackendEngineering #Concurrency #Payments #SystemDesign #RESTAPI #SoftwareEngineering #LearningInPublic #Fintech
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