walterwanderley / sqlc-grpc

Create a gRPC server from code generated by sqlc
MIT License
123 stars 13 forks source link

Transactions #4

Closed JamesArthurHolland closed 1 year ago

JamesArthurHolland commented 1 year ago

Is there a way to use transactions?

If you're familiar with gqlgen, the resolvers file is able to be editted, despite it being generated.

Would be good for the author service to have this functionality, or else have a "controller" that wraps the services that could have this functionality. Similar to the resolver pattern in graphql.

walterwanderley commented 1 year ago

Yes! With version v0.15.0 you can use the WithTx method to use transactions in a decorator/wrapper service.

Example:

// /internal/authors/transactions.go
package authors

import (
    "context"
    "database/sql"

    pb "authors/api/authors/v1"
)

type TransactionalService struct {
    *Service
    db *sql.DB
}

func (s *TransactionalService) CreateAuthor(ctx context.Context, req *pb.CreateAuthorRequest) (*pb.CreateAuthorResponse, error) {
    tx, err := s.db.BeginTx(ctx, &sql.TxOptions{})
    if err != nil {
        return nil, err
    }
    defer tx.Rollback()

    service := s.WithTx(tx)

    // do some transactional operations with tx....
    resp, err := service.CreateAuthor(ctx, req)
    if err != nil {
        return nil, err
    }
    err = tx.Commit()
    return resp, err
}
// /internal/authors/service.factory.go
package authors

import (
    "database/sql"

    "go.uber.org/zap"

    pb "authors/api/authors/v1"
)

// NewService is a constructor of a pb.AuthorsServiceServer implementation.
// Use this function to customize the server by adding middlewares to it.
func NewService(logger *zap.Logger, querier *Queries, db *sql.DB) pb.AuthorsServiceServer {
    return &TransactionalService{
        Service: &Service{
            logger:  logger,
            querier: querier,
        },
        db: db,
    }
}

You can add new services with go generate. Your wrappers will not be changed by sqlc.-grpc.

gedw99 commented 1 year ago

@walterwanderley this is really great work..