DDD & DB Transactions (unit of work?)

Published 1 week ago by phx93

I'm using DDD (Service -> Repository -> Model) and MVC.

Where should I place my transactions (maybe unit of work lite)? Controllers? Services?

The repositories doesn't seem like a good place since a service might use multiple repositories to create a complete domain object. In e.g. when calling startNewOrder on the OrderService, it creates both a Order and OrderEvents using respectively repository. This needs to happen in the same database transaction.

Doing this in the service seems a bit dirty to me:

class OrderService
{
    ...
    public function startNewOrder($order, $facility_id)
    {
         DB::beginTransaction();
         
         try {
             $order = $this->order->create($order);
             $this->orderEvent->createFirst($order['id'], $facility_id);
             DB::commit();
         } catch (Throwable $e) {
             DB::rollback();
             throw $e;
         }
    }
}
phx93
phx93
6 days ago (2,690 XP)

Ended up doing this:

class OrderService
{
    ...
    public function startNewOrder($order, $facility_id)
    {
         $this->uow->beginTransaction();

         try {
             $order = $this->order->create($order);
             $this->orderEvent->createFirst($order['id'], $facility_id);
             $this->uow->commit();
         } catch (Throwable $e) {
             $this->uow->rollback();
             throw $e;
         }
    }
}
martinbean

@phx93 I think you’re going to have a hard time implementing enterprise patterns like Unit of Work if you’re using Eloquent under the hood as well.

Eloquent already implements the Active Record pattern in an opinionated manner. It also knows how to retrieve and persist from the database. If you go the approach outlined above, then you’re very quickly going to have lots of services doing transactions.

phx93
phx93
6 days ago (2,690 XP)

@martinbean How should I handle transactions in my services? Or do you mean that my services shouldn't handle transactions?

I only need to call the uow class when in need of transactions in my services. This isn't a full blown UoW class but I didn't come up with any better naming for this. Maybe I should have named the class TransactionService instead.

Please sign in or create an account to participate in this conversation.