transaction_manager

package module
v0.0.0-...-4b0a3d7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 14, 2024 License: GPL-3.0 Imports: 1 Imported by: 0

README

Golang Transaction Manager

Go Report Card Go Go Doc Release

Transaction manager is an abstraction to coordinate database transaction boundaries.

Easiest way to get the perfect repository.

Supported implementations

Installation

go get github.com/moguchev/transaction_manager

Usage

Examples

Below is an example how to start usage.

  1. Implement a Transaction Manager at your Repository Layer
import pgxv5_transaction_manager "github.com/moguchev/transaction_manager/postgres/pgxv5"

type repo struct {
	driver pgxv5_transaction_manager.QueryEngineProvider // <-- add this one
}

func (r *repo) Foo(ctx context.Context, v int) error {
    db := r.driver.GetQueryEngine(ctx) // <-- instead of pgx.Pool/pgx.Tx direct call

	_, err := db.Exec(ctx, "INSERT INTO test_table_1 (id) VALUES ($1)", v)

	return err
}

func (r *repo) Bar(ctx context.Context, v int) error {
    db := r.driver.GetQueryEngine(ctx) // <-- instead of pgx.Pool/pgx.Tx direct call

	_, err := db.Exec(ctx, "INSERT INTO test_table_2 (id) VALUES ($1)", v)

	return err
}
  1. Use Transaction Manager in your code
import "github.com/moguchev/transaction_manager"

// repoInterface - your dependency
type repoInterface interface {
	Foo(ctx context.Context, v int) error
	Bar(ctx context.Context, v int) error
}


// example - your business logic
type example struct {
	transactionManager transaction_manager.TransactionManager // <-- add this one

	repo repoInterface
}

// Create - some usecase...
func (ex *example) Create(ctx context.Context, id int) error {
	// ...

	transaction := func(txCtx context.Context) error { // Begin of Transaction Scope
		// Foo & Bar will be called in one transaction
		// (if repo supports transaction manager)

		if err := ex.repo.Foo(txCtx, id); err != nil {
			return fmt.Errorf("foo: %w", err)
		}

		if err := ex.repo.Bar(txCtx, id); err != nil {
			return fmt.Errorf("foo: %w", err)
		}

		return nil
	} // End of Transaction Scope

	return ex.transactionManager.RunTransaction(ctx, transaction,
        // additional options for out transaction without any influence on our code
        // (easy to mock)
		pgxv5_transaction_manager.WithAccessMode(pgx.ReadWrite),
		pgxv5_transaction_manager.WithIsoLevel(pgx.ReadCommitted),
		pgxv5_transaction_manager.WithDeferrableMode(pgx.Deferrable),
	)
}
  1. Initialize Transaction Manager and use dependency injection to your objects
func main() {
	ctx := context.Background()

	pool, err := pgxpool.New(ctx, os.Getenv("POSTGRES_DSN"))
	if err != nil {
		log.Fatal(err)
	}
	defer pool.Close()

	txManager := pgxv5_transaction_manager.New(pool)

    repo := &repo{
		driver: txManager,
	}

	ex := example{
		repo:               repo,
		transactionManager: txManager,
	}

	if err := ex.Create(ctx, 1); err != nil {
		log.Fatal(err)
	}
    log.Println("OK")
}

Other projects

Documentation

Overview

Package transaction_manager

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type TransactionManager

type TransactionManager interface {
	RunTransaction(ctx context.Context, fn func(txCtx context.Context) error, opts ...TransactionOption) error
}

TransactionManager - transaction manager interface

type TransactionOption

type TransactionOption func(x any)

TransactionOption - any transaction option

Directories

Path Synopsis
examples
postgres/pgxv5 command
postgres

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL