Skip to main content

Posts

Showing posts with the label Hexagonal Architecture

Handling Database Transactions in Hexagonal Architecture Without Leaking Abstractions

  The Blocker: The "Transactional" Annotation Trap You have meticulously designed your Hexagonal Architecture (Ports & Adapters). You have a pristine Domain layer and a segregated Application (Use Case) layer. You have stripped away all frameworks from your core. Then, you write a Use Case that requires atomicity: Deduct inventory. Charge the credit card. Save the order. If any step fails, all must fail. The instinct is to reach for a framework-specific annotation (like Spring’s  @Transactional  or NestJS interceptors) and slap it on the Use Case method. Stop. The moment you import  org.springframework.transaction.annotation.Transactional  (or similar) into your Use Case layer, you have violated the  Dependency Rule . Your inner circle now depends on a framework mechanism living in the outer circle. You are no longer framework-agnostic. If you swap the persistence adapter or the framework, your business logic breaks. The Root Cause: Mixing Business Boun...

Transactional Consistency in Hexagonal Architecture: The Unit of Work Pattern

  The hardest boundary to maintain in Hexagonal Architecture (Ports and Adapters) is the one between your Application layer and your Persistence layer when   ACID transactions   are involved. You have likely faced this dilemma: The "Dirty" Approach:  You pass a database transaction object (like JPA’s  EntityManager  or a Prisma  tx  client) into your Domain services.  Result:  Your domain is now coupled to your database library. The "Magic" Approach:  You rely on framework decorators like  @Transactional  (Spring/NestJS).  Result:  This often works for simple CRUD, but fails when composing complex Use Cases where the transaction boundary needs to be explicit, or when you are strictly separating your core logic into libraries that do not depend on the framework. In a strict Clean Architecture, the Use Case (Application Service) dictates the transaction boundary, but the Domain layer must remain ignorant of  h...