go-ddd icon indicating copy to clipboard operation
go-ddd copied to clipboard

Idea on handling transactions?

Open SeaRoll opened this issue 1 year ago • 4 comments

Is there anyone who has tried ddd with transactions?

SeaRoll avatar Oct 27 '24 04:10 SeaRoll

Hi @SeaRoll, my 2 cents: The application layer should begin the transaction (as early as possible) as it coordinates the workflow of domain operations.

Example (untested):

func (s *Service) PerformOperation(ctx context.Context, input InputDTO) error {
    tx := s.db.Begin() // Start the transaction
    defer func() {
        if r := recover(); r != nil {
            tx.Rollback()
        }
    }()

    // Perform domain operations using repositories
    err := s.repo.DoSomething(tx, input)
    if err != nil {
        tx.Rollback()
        return err
    }

    err = s.repo.DoAnotherThing(tx, input)
    if err != nil {
        tx.Rollback()
        return err
    }

    return tx.Commit().Error // Commit the transaction
}

sklinkert avatar Oct 27 '24 16:10 sklinkert

Amazing, thank you!

SeaRoll avatar Oct 29 '24 00:10 SeaRoll

does not this approach lead to leakage on the application/domain? 🤔

SeaRoll avatar Oct 29 '24 23:10 SeaRoll

Kind of does.

I would suggest to call

op, err := s.repository.BeginOperation(context.Context) (operation.Operation, error)
defer op.Commit() // op.Rollback()

In this case you can provide operation op as is, or even inject it to context ctx = op.Context() to be extracted on repository level later.

In both ways you work with abstract operation that makes your actions atomic, however it doesn't lead to leakage of the repository internals.

spatecon avatar Mar 13 '25 15:03 spatecon