tx

package
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 6, 2018 License: MIT Imports: 5 Imported by: 0

README

tx

Package tx provides a simple transaction abstraction I created to be used mostly by data-mappers/repositories in order to decouple persistence from application/domain logic. (Something like @Transactional annotation in Java, without an annotation)

Usage

In order to use tx package, your persistence abstractions (be it repositories or anything else) need to implement tx.Transactional interface containing three relatively simple methods:

type Transactional interface {
	// RunTx should create new client side transaction object that can
	// be used to Commit or Rollback the transaction at a later point, and
	// wrap into *Tx by using tx.Wrap and then it should call tx.Run
	//
	// Example body:
	// {
	// 	t, _ := sql.BeginTx(ctx) // create client side transaction object
	// 	transaction := tx.Wrap(t) // wrap it inside of a tx transaction

	// TODO - Add any meta data you might need later to the transaction

	// 	return tx.Run(ctx, ur, transaction, f)
	// }
	RunTx(context.Context, func(context.Context) error) error

	// Commit is called every time RunTx transaction func returns nil error
	// indicating that transaction shuld be commited
	//
	// If Commit returns an error it is propagated and returned by RunTx
	//
	// Commit should never be called directly by client code
	Commit(*Tx) error

	// Rollback is called every time RunTx transaction func
	// returns an error indicating that transaction should be aborted
	//
	// If Rollback returns an error it wraps the error returned from
	// transaction func and both are propagated and returned by RunT
	//
	// Rollback should never be called directly by client code
	Rollback(*Tx) error
}

This packages also provides simple default Transactional implementations which you can use by simply embedding them inside of your database access objects.

Example:

func NewAccountDB(db *sql.DB) *AccountDB {
    return &AccountDB{
        SQL: tx.SQL{
            DB: db,
        }
    }
}

type AccountDB struct {
    tx.SQL
}

Available transactional implementations:

See example package for a full example implementation.

Application service

Ultimately you want to use it inside of your application service use case, eg:

svc.accounts.RunTx(
	ctx,
	// This func will be run in a transaction
	// It is crucial for you to use the context provided by the
	// call to this function, otherwise statements will not be run in a transaction
	func(ctx context.Context) error {

		// Use your repo methods here passing in ctx	

		return nil
	},
)

See example package for a full example implementation.

Stuff I might implement:
  • Transaction options
  • Transaction meta data

Documentation

Overview

Package tx provides a simple implementation agnostic transaction abstraction

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Run

func Run(ctx context.Context, t Transactional, tx *Tx, f func(context.Context) error) (err error)

Run runs provided func as a transaction

Non nil error returned by the function is considered to indicate that the transaction should be rolled back, accordingly, nil error indicates that the transaction should be commited by calling Commit and Rollback methods on a registered repository respectively

Types

type SQL

type SQL struct {
	DB *sql.DB
}

SQL is a sql implementation of Transactional interface It is meant to be used as a helper and embedded inside of data access objects such as a repositories in order to provide them with decoupled sql transaction behavior

func (SQL) Commit

func (SQL) Commit(tx *Tx) error

Commit commits sql transaction

func (SQL) Rollback

func (SQL) Rollback(tx *Tx) error

Rollback rolls back sql transaction

func (*SQL) RunTx

func (sql *SQL) RunTx(ctx context.Context, f func(context.Context) error) error

RunTx runs f in a SQL transaction

type Transactional

type Transactional interface {

	// 	return tx.Run(ctx, ur, transaction, f)
	// }
	RunTx(context.Context, func(context.Context) error) error

	// Commit is called every time RunTx transaction func returns nil error
	// indicating that transaction shuld be commited
	//
	// If Commit returns an error it is propagated and returned by RunTx
	//
	// Commit should never be called directly by client code
	Commit(*Tx) error

	// Rollback is called every time RunTx transaction func
	// returns an error indicating that transaction should be aborted
	//
	// If Rollback returns an error it wraps the error returned from
	// transaction func and both are propagated and returned by RunT
	//
	// Rollback should never be called directly by client code
	Rollback(*Tx) error
}

Transactional interface should be implemented by an object wanting to use transactions

type Tx

type Tx struct {
	// contains filtered or unexported fields
}

Tx represents transaction object

func Current

func Current(ctx context.Context) (*Tx, bool)

Current extracts Tx object from context if any Returns nil, false if not in a transaction

func Wrap

func Wrap(clientTx interface{}) *Tx

Wrap creates new transaction and wraps provided client transaction to be used by the subsequent client side calls and ultimately by Commit and Rollback methods

func (*Tx) Unwrap

func (tx *Tx) Unwrap() interface{}

Unwrap unwraps the underlying client transaction wrapped by a call to tx.Wrap

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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