The Domain Model isn't the place to manage transactions. The operations applied over the Domain Model should be agnostic to the persistence mechanism. A common approach to solving this problem is placing a Facade in the Application layer, thereby grouping related use cases together. When a method of the Facade is invoked from the UI layer, the business method begins a transaction. Once complete, the Facade ends the interaction by committing the transaction. If anything goes wrong, the transaction is rolled back:
use Doctrine\ORM\EntityManager;
class SomeApplicationServiceFacade
{
private $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
public function doSomeUseCaseTask()
{
try {
$this->em->getConnection()->beginTransaction();
// Use domain model
$this->em->getConnection()->commit...