ddd-aggregate-transaction-boundary

Detects and corrects multi-aggregate transactions in DDD use cases using eventual consistency patterns.

Updated Jun 23, 2026
One-click install
npx skills add https://github.com/j5ik2o/marp-ai-base --skill ddd-aggregate-transaction-boundary-j5ik2o
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: ddd-aggregate-transaction-boundary
Source: https://github.com/j5ik2o/marp-ai-base/tree/main/.agents/skills/ddd-aggregate-transaction-boundary
Command: npx skills add https://github.com/j5ik2o/marp-ai-base --skill ddd-aggregate-transaction-boundary-j5ik2o

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? It identifies the anti-pattern of updating multiple DDD aggregates within a single transaction, which violates aggregate boundaries, blocks scalability, and prevents future microservice decomposition. ## Core Features & Use Cases - Anti-pattern Detection: Reviews use case code for @Transactional scopes spanning multiple repositories or aggregates. - Modeling Guidance: Provides a decision flow for merging 1:1 aggregates, applying CQRS read models, or splitting into separate aggregates. - Eventual Consistency Implementation: Shows how to coordinate aggregates via domain events, Outbox pattern, retries, and Saga compensation. - Use Case: During a code review, you find a CreateTaskUseCase with @Transactional inserting both Task and TaskReport; the skill guides you to either merge them into one aggregate or connect them via a TaskCreated domain event handled in a separate transaction. ## Quick Start Review this use case that updates multiple aggregates in one transaction and refactor it to follow the one-transaction-one-aggregate rule with eventual consistency.

Frequently Asked Questions about ddd-aggregate-transaction-boundary

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I handle transactions across multiple DDD aggregates?

Keep each aggregate in its own transaction and coordinate them with eventual consistency. Publish domain events from the first aggregate and handle them in separate transactions to update other aggregates.

Why is updating multiple aggregates in one transaction an anti-pattern?

Aggregates are strong consistency boundaries by definition, so combining them creates implicit coupling. This blocks independent scaling, prevents splitting into microservices, and fails when aggregates use different data stores.

When should two aggregates be merged into one instead?

Merge them when they have a 1:1 relationship and are always updated together, such as a Task and its TaskReport. For 1:N relationships with small N, consider requirement adjustments before merging.

How do I solve the dual-write problem with domain events?

Use the Outbox pattern to guarantee event publication alongside aggregate persistence. For failures, apply retries for transient errors or Saga compensation transactions for complex multi-aggregate coordination.

Does this transaction boundary rule apply to languages other than Kotlin?

Yes, the principle is language-independent and applies to Java, Scala, TypeScript, Go, Rust, Python, and others. Any transaction control mechanism spanning multiple repositories triggers the same review.