mercredi 3 novembre 2021

How to structure my Go app for transactions via pgx

I have the following models

type UsersModel struct {
    db           *pgx.Conn
}

func (u *UsersModel) SignupUser(ctx context.Context, payload SignupRequest) (SignupQueryResult, error) {
    err := u.db.Exec("...")
    return SignupQueryResult{}, err
}
type SessionsModel struct {
    db           *pgx.Conn
}
 
func (s *SessionsModel) CreateSession(ctx context.Context, payload CreateSessionRequest) error {
    _, err := s.db.Exec("...")
    return err
}

and my service calls UsersModel.SignupUser as follows

type SignupService struct {
    userModel signupServiceUserModel
}

func (ss *SignupService) Signup(ctx context.Context, request SignupRequest) (SignupQueryResult, error) {
    return ss.userModel.SignupUser(ctx, request)
}

Now, I need to tie SignupUser and CreateSession in a transaction instead of isolated operations, not sure what the best way to structure this is, and how to pass transaction around while maintaining that abstraction of DB specific stuff from services. Or should I just call the sessions table insert query(which I'm putting in *SessionsModel.CreateSession directly in *UsersModel.SignupUser?

For reference, transactions in pgx happen by calling *pgx.Conn.Begin() which returns a concrete pgx.Tx , on which you execute the same functions as you would on *px.Conn , followed by *pgx.Tx.Commit() or *pgx.Tx.Rollback()

Questions I have are:

  • Where to start transaction - model or service?
  • If in service, how do I do that while abstracting that there's an underlying DB from service?
  • How do I pass transaction between models?

Aucun commentaire:

Enregistrer un commentaire