Skip to content

Instantly share code, notes, and snippets.

@donchev7
Created August 17, 2024 11:45
Show Gist options
  • Save donchev7/fa2d48fe957aed45ee16d69cb7dc495b to your computer and use it in GitHub Desktop.
Save donchev7/fa2d48fe957aed45ee16d69cb7dc495b to your computer and use it in GitHub Desktop.
tx in go
package repository
import (
"context"
"fmt"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/quantum-wealth/search-service/internal/repository/model"
"github.com/quantum-wealth/search-service/pkg/pg"
"github.com/rs/zerolog/log"
)
type Repository struct {
queries *model.Queries
db *pgxpool.Pool
}
type txRepository struct {
*model.Queries
}
func New() Repository {
return Repository{
queries: model.New(pg.DB),
db: pg.DB,
}
}
func withTx[T any](ctx context.Context, r Repository, fn func(txRepository) (T, error)) (T, error) {
tx, err := r.db.Begin(ctx)
if err != nil {
var zero T
return zero, fmt.Errorf("failed to begin transaction: %w", err)
}
txRepo := txRepository{
Queries: r.queries.WithTx(tx),
}
var result T
defer func() {
if p := recover(); p != nil {
_ = tx.Rollback(ctx)
panic(p) // Re-panic after ensuring the transaction is rolled back
}
}()
result, err = fn(txRepo)
if err != nil {
if rbErr := tx.Rollback(ctx); rbErr != nil {
log.Ctx(ctx).Error().Err(rbErr).Msg("failed to rollback transaction")
}
return result, err
}
if err = tx.Commit(ctx); err != nil {
return result, fmt.Errorf("failed to commit transaction: %w", err)
}
return result, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment