Closed JamesArthurHolland closed 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.
@walterwanderley this is really great work..
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.