codeliner / php-ddd-cargo-sample

PHP 7 Version of the cargo sample used in Eric Evans DDD book
http://codeliner.github.io/php-ddd-cargo-sample/
BSD 3-Clause "New" or "Revised" License
796 stars 151 forks source link

TrasactionManager in BookingService #31

Closed zvuki closed 7 years ago

zvuki commented 8 years ago

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.

codeliner commented 8 years ago

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.

zvuki commented 8 years ago

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!

codeliner commented 8 years ago

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.

codeliner commented 7 years ago

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

codeliner commented 7 years ago

Closed by #35