codeliner / php-ddd-cargo-sample

PHP 7 Version of the cargo sample used in Eric Evans DDD book

Home Page:http://codeliner.github.io/php-ddd-cargo-sample/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

TrasactionManager in BookingService

zvuki opened this issue · comments

Hey,

it's not a real issue, maybe Evans has the same in his book (I didn't read it), but I am curious about transactions in service.

https://github.com/codeliner/php-ddd-cargo-sample/blob/master/CargoBackend/src/Application/Booking/BookingService.php#L88

When we have it there, it introduces a DB dependency in application service layer, which is "not nice", as db-handling is a responsibility of another layer (Repository or even deeper).

As we have a simple Entity, no even an Aggregate Root, we can live easily without this transaction or we could hide it inside Repository. What do you think?

My question is whether it's done intentionally or there is no really good reason.

hey @zvuki, the java version of the cargo sample also manages transaction on application level, see here: https://github.com/citerus/dddsample-core/blob/master/src/main/java/se/citerus/dddsample/application/impl/BookingServiceImpl.java#L33

The reason for this is that a bounded context forms the transaction boundary. Every action triggered in the model should be wrapped in a transaction. Sure you can hide the transaction in the repository, but then you need to be very very careful as really only one AR can be modified in a safe way within a single request. This is recommended but not always possible. When working with doctrine and associations between entities you might modify more than one in a request. When managing the transaction in an application service that owns the use case triggered by the request you can make sure that either all changes are committed or rolled back.

This way you have to mock TransactionManager in unit tests, which is not the end of the world of course, my gut feeling it doesn't belong there. Anyway, I completely understand the reasoning.

Thank you for the answer!

You are right. a TransactionManager interface would be better and then a DoctrineTransactionManager implementation. This way the transaction manager can easily be mocked. Let's keep the question open until this is changed.

Someone interested in providing a TransactionManager interface? Drop me a note here!