Back to articles
Stop Passing *sql.Tx Through Your Go Service Layer

Stop Passing *sql.Tx Through Your Go Service Layer

via Dev.toGabriel Anhaia

Your service needs to save an order and reserve inventory. Both must succeed or neither should. The instinct: func ( s * Service ) PlaceOrder ( ctx context . Context , tx * sql . Tx , req Request ) error { if err := s . orderRepo . SaveWithTx ( ctx , tx , order ); err != nil { return err } if err := s . inventoryRepo . ReserveWithTx ( ctx , tx , order . Items ); err != nil { return err } return nil } This compiles. It works. And it destroys your architecture. What's Wrong Your domain now imports database/sql . The service knows what a SQL transaction is. Every port needs a "WithTx" variant. Your in-memory test doubles are useless — they can't accept *sql.Tx . And if you ever move to DynamoDB? Its transactional model is completely different. You're locked in. The domain should express what needs to happen atomically. The adapter should decide how . The Unit of Work Pattern Define a port that says "execute these operations as one atomic unit" without specifying the mechanism: type OrderS

Continue reading on Dev.to

Opens in a new tab

Read Full Article
2 views

Related Articles