Reputation: 13187
I'm trying to implement Domain Driven Design with Unit Of Pattern in my app using ASP.Net WebApi.
1) Where should I start/commit transactions (API controller, application layer/service, DAL, domain layer/service)?
2) What is the best way to manage transactions in complex application with a lot of bussines rules (AOP, explicit call or somehow else)?
3) What is the best way to reuse one piece of code with transaction in more bigger transaction? i.g. I have independent use case - close invoice - which contains the transaction already. Also this code contains some non domain code like logging, statistics counting and etc. And I want to reuse this code in more complex use case - paying invoice, deduction of commissions and closing invoice.
3.1) How you deal with an inner transaction problem (popular databases don't support it)?
3.2) What should layer be responsible for this?
I know answers may depend on a particular project. But it would be great to consider any workable in real projects techniques
Upvotes: 6
Views: 3310
Reputation: 7285
1) Where should I start/commit transactions (API controller, application layer/service, DAL, domain layer/service)?
Transactions is a concern of the application layer.
2) What is the best way to manage transactions in complex application with a lot of bussines rules (AOP, explicit call or somehow else)?
It kinda depends on the persistence/ORM framework that you are using. Entity Framework and NHibernate supports change tracking can make unit of work (commit and rollbacks) easy for you. To ensure changes are made within the same transaction, the repositories must use same unit of work instance (eg. DbContext, session)
3) What is the best way to reuse one piece of code with transaction in more bigger transaction? i.g. I have independent use case - close invoice - which contains the transaction already. Also this code contains some non domain code like logging, statistics counting and etc. And I want to reuse this code in more complex use case - paying invoice, deduction of commissions and closing invoice.
Logging are cross-cutting concerns and should not affect the use case. These kind of dependencies are injected via the constructor or property. Use an inversion of control container like unity.
Upvotes: 7
Reputation: 14064
1) The Application layer starts a Unit of Work which turns to the Infrastructure side to initiate whichever sort of technical transaction supports the operation. Same for committing.
2) Exactly the same way as smaller applications. Transactions usually take place around Aggregates no matter the number of business rules. For very long running, very complex multi part use cases, you could use Sagas.
3) A few options, in order of preference : 1. Just reuse the domain and subscribe to domain events to manage things such as stats or logging. 2. In the Application layer, share code between the bigger and smaller use cases, but not transaction / UoW code. Keep it all inside a single transaction. 3. Use a process manager to coordinate calls to smaller use cases as part of a bigger use case (Saga).
Upvotes: 5