Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate drivers #92

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 3 additions & 11 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -112,19 +112,11 @@ jobs:
- name: Tests with real databases
run: make test.coverage.with_real_db

- name: Code coverage data
run: |
set -x
COVERAGE_TOTAL=`go tool cover -func=coverage.out | grep total | grep -Eo '[0-9]+\.[0-9]+'`
echo "COVERAGE_TOTAL=$COVERAGE_TOTAL" >> $GITHUB_ENV
- uses: jandelgado/[email protected]
with:
outfile: ./coverage.lcov

- name: Coveralls
uses: coverallsapp/github-action@master
uses: coverallsapp/github-action@v2
with:
path-to-lcov: ./coverage.lcov
format: golang
file: ./coverage.out
github-token: ${{ secrets.GITHUB_TOKEN }}

golangci:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ vendor/

# Code coverage
coverage.*
coverage/
6 changes: 3 additions & 3 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,14 @@ issues:
linters:
- staticcheck
text: "SA1029: should not use built-in type string as key for value; define your own type to avoid collisions"
- path: .+/context\.go
- path: (.+/)?context\.go
linters:
- ireturn
- path: .+/transaction\.go
- path: (.+/)?transaction\.go
linters:
- ireturn
source: \) Begin\(ctx
- path: .+/settings\.go
- path: (.+/)?settings\.go
linters:
- ireturn
source: "(?:EnrichBy|SetPropagation|SetCtxKey|CtxKey|SetCancelable|SetTimeout)"
Expand Down
26 changes: 19 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
CVPKG=go list ./... | grep -v mocks | grep -v internal/
GO_TEST=go test `$(CVPKG)` -race
GO_TEST_WITH_REAL_DB=$(GO_TEST) --tags=with_real_db
COVERAGE_FILE="coverage.out"
DIR=$(PWD)

GO_TEST=cd ./sh && bash ./go.test.sh
GO_TEST_COVERAGE=cd ./sh && bash ./go.test.coverage.sh

GO_TEST_WITH_REAL_DB=--tags=with_real_db

test:
$(GO_TEST)

test.with_real_db:
$(GO_TEST_WITH_REAL_DB)
$(GO_TEST) $(GO_TEST_WITH_REAL_DB)

test.coverage:
$(GO_TEST) -covermode=atomic -coverprofile=$(COVERAGE_FILE)
$(GO_TEST_COVERAGE)

test.coverage.with_real_db:
$(GO_TEST_WITH_REAL_DB) -covermode=atomic -coverprofile=$(COVERAGE_FILE)
$(GO_TEST_COVERAGE) $(GO_TEST_WITH_REAL_DB)

fmt:
go fmt ./...
Expand All @@ -23,3 +25,13 @@ lint:

generate:
go generate ./...


go.mod.tidy:
cd sh && sh ./go.mod.tidy.sh

go.mod.vendor:
cd sh && sh ./go.mod.vendor.sh

go.work.sync:
cd sh && sh ./go.work.sync.sh
69 changes: 45 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Go transaction manager

[![Go Reference](https://pkg.go.dev/badge/github.com/avito-tech/go-transaction-manager.svg)](https://pkg.go.dev/github.com/avito-tech/go-transaction-manager)
[![Go Reference](https://pkg.go.dev/badge/github.com/avito-tech/go-transaction-manager.svg)](https://pkg.go.dev/github.com/avito-tech/go-transaction-manager/v2)
[![Test Status](https://github.com/avito-tech/go-transaction-manager/actions/workflows/main.yaml/badge.svg)](https://github.com/avito-tech/go-transaction-manager/actions?query=branch%3Amain)
[![Coverage Status](https://coveralls.io/repos/github/avito-tech/go-transaction-manager/badge.svg?branch=main)](https://coveralls.io/github/avito-tech/go-transaction-manager?branch=main)
[![Go Report Card](https://goreportcard.com/badge/github.com/avito-tech/go-transaction-manager)](https://goreportcard.com/report/github.com/avito-tech/go-transaction-manager)
[![Go Report Card](https://goreportcard.com/badge/github.com/avito-tech/go-transaction-manager)](https://goreportcard.com/report/github.com/avito-tech/go-transaction-manager/v2)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

Transaction manager is an abstraction to coordinate database transaction boundaries.
Expand All @@ -12,45 +12,57 @@ Easiest way to get the perfect repository.

## Supported implementations

* [database/sql](https://pkg.go.dev/database/sql), [docs](https://pkg.go.dev/github.com/avito-tech/go-transaction-manager/sql) (Go 1.13)
* [jmoiron/sqlx](https://github.com/jmoiron/sqlx), [docs](https://pkg.go.dev/github.com/avito-tech/go-transaction-manager/sqlx) (Go 1.13)
* [gorm](https://github.com/go-gorm/gorm), [docs](https://pkg.go.dev/github.com/avito-tech/go-transaction-manager/gorm) (Go 1.16)
* [mongo-go-driver](https://github.com/mongodb/mongo-go-driver), [docs](https://pkg.go.dev/github.com/avito-tech/go-transaction-manager/mongo) (Go 1.13)
* [go-redis/redis](https://github.com/go-redis/redis), [docs](https://pkg.go.dev/github.com/avito-tech/go-transaction-manager/redis) (Go 1.17)
* [pgx_v4](https://github.com/jackc/pgx/tree/v4), [docs](https://pkg.go.dev/github.com/avito-tech/go-transaction-manager/pgxv4) (Go 1.16)
* [pgx_v5](https://github.com/jackc/pgx), [docs](https://pkg.go.dev/github.com/avito-tech/go-transaction-manager/pgxv5) (Go 1.19)
* [database/sql](https://pkg.go.dev/database/sql), [docs](https://pkg.go.dev/github.com/avito-tech/go-transaction-manager/v2/drivers/sql/v2) (
Go 1.13)
* [jmoiron/sqlx](https://github.com/jmoiron/sqlx), [docs](https://pkg.go.dev/github.com/avito-tech/go-transaction-manager/v2/drivers/sqlx/v2) (
Go 1.13)
* [gorm](https://github.com/go-gorm/gorm), [docs](https://pkg.go.dev/github.com/avito-tech/go-transaction-manager/v2/drivers/gorm/v2) (
Go 1.18)
* [mongo-go-driver](https://github.com/mongodb/mongo-go-driver), [docs](https://pkg.go.dev/github.com/avito-tech/go-transaction-manager/v2/drivers/mongo/v2) (
Go 1.13)
* [go-redis/redis](https://github.com/go-redis/redis), [docs](https://pkg.go.dev/github.com/avito-tech/go-transaction-manager/v2/drivers/goredis8/v2) (
Go 1.17)
* [pgx_v4](https://github.com/jackc/pgx/tree/v4), [docs](https://pkg.go.dev/github.com/avito-tech/go-transaction-manager/v2/drivers/pgxv4/v2) (
Go 1.16)
* [pgx_v5](https://github.com/jackc/pgx), [docs](https://pkg.go.dev/github.com/avito-tech/go-transaction-manager/v2/drivers/pgxv5/v2) (
Go 1.19)

## Installation

```bash
go get github.com/avito-tech/go-transaction-manager
go get github.com/avito-tech/go-transaction-manager/v2
```

To install some support database use `go get github.com/avito-tech/go-transaction-manager/v2/drivers/{name}`.

For example `go get github.com/avito-tech/go-transaction-manager/v2/drivers/sqlx/v2`.

### Backwards Compatibility

The library is compatible with the most recent two versions of Go.
Compatibility beyond that is not guaranteed.

## Usage

**To use multiple transactions from different databases**, you need to set CtxKey in [Settings](trm/settings.go) by [WithCtxKey](trm/settings/option.go).
**To use multiple transactions from different databases**, you need to set CtxKey in [Settings](trm/settings.go)
by [WithCtxKey](settings/option.go).

**For nested transactions with different transaction managers**, you need to use [ChainedMW](trm/manager/chain.go) ([docs](https://pkg.go.dev/github.com/github.com/avito-tech/go-transaction-manager)).
**For nested transactions with different transaction managers**, you need to
use [ChainedMW](manager/chain.go) ([docs](https://pkg.go.dev/github.com/github.com/avito-tech/go-transaction-manager)).

**To skip a transaction rollback due to an error, use [ErrSkip](trm/manager.go#L20) or [Skippable](trm/manager.go#L24)**
**To skip a transaction rollback due to an error, use [ErrSkip](manager.go#L20) or [Skippable](manager.go#L24)**

### Explanation of the approach ([English](https://www.youtube.com/watch?v=aRsea6FFAyA), [Russian](https://habr.com/ru/companies/avito/articles/727168/))

### Examples with an ideal *repository* and nested transactions.

* [database/sql](sql/example_test.go)
* [jmoiron/sqlx](sqlx/example_test.go)
* [gorm](gorm/example_test.go)
* [mongo-go-driver](mongo/example_test.go)
* [go-redis/redis](redis/example_test.go)
* [pgx_v4](pgxv4/example_test.go)
* [pgx_v5](pgxv5/example_test.go)

* [database/sql](drivers/sql/example_test.go)
* [jmoiron/sqlx](drivers/sqlx/example_test.go)
* [gorm](drivers/gorm/example_test.go)
* [mongo-go-driver](drivers/mongo/example_test.go)
* [go-redis/redis](drivers/goredis8/example_test.go)
* [pgx_v4](drivers/pgxv4/example_test.go)
* [pgx_v5](drivers/pgxv5/example_test.go)

Below is an example how to start usage.

Expand All @@ -64,8 +76,8 @@ import (
"github.com/jmoiron/sqlx"
_ "github.com/mattn/go-sqlite3"

trmsqlx "github.com/avito-tech/go-transaction-manager/sqlx"
"github.com/avito-tech/go-transaction-manager/trm/manager"
trmsqlx "github.com/avito-tech/go-transaction-manager/v2/drivers/sqlx/v2"
"github.com/avito-tech/go-transaction-manager/v2/manager"
)

func main() {
Expand All @@ -85,6 +97,7 @@ func main() {
err = trManager.Do(ctx, func(ctx context.Context) error {
checkErr(r.Save(ctx, u))

// example of nested transactions
return trManager.Do(ctx, func(ctx context.Context) error {
u.Username = "new_username"
return r.Save(ctx, u)
Expand Down Expand Up @@ -146,4 +159,12 @@ func (r *repo) Save(ctx context.Context, u *user) error {

## Benchmark

[Comparing](internal/benchmark/with_or_without_trm/README.md) examples with and without trm.
[Comparing](internal/benchmark/with_or_without_trm/README.md) examples with and without trm.

## Contribution

1. To local development sync dependencies by `make go.work.sync`.
2. After finalizing of changes bump up version in all drivers.

* To install all dependencies use `make go.mod.tidy` or `make go.mod.vendor`.
* To run all tests use `make go.test` or `make go.test.with_real_db` for integration tests.
File renamed without changes.
4 changes: 2 additions & 2 deletions trm/context/context.go → context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ package context
import (
"context"

"github.com/avito-tech/go-transaction-manager/trm"
"github.com/avito-tech/go-transaction-manager/trm/settings"
trm "github.com/avito-tech/go-transaction-manager/v2"
"github.com/avito-tech/go-transaction-manager/v2/settings"
)

// DefaultManager is a trm.СtxManager with settings.DefaultCtxKey.
Expand Down
2 changes: 1 addition & 1 deletion trm/context/key.go → context/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package context
import (
"sync/atomic"

"github.com/avito-tech/go-transaction-manager/trm"
trm "github.com/avito-tech/go-transaction-manager/v2"
)

//nolint:gochecknoglobals
Expand Down
File renamed without changes.
12 changes: 6 additions & 6 deletions redis/context.go → drivers/goredis8/context.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package redis
package goredis8

import (
"context"

"github.com/go-redis/redis/v8"

"github.com/avito-tech/go-transaction-manager/trm"
trmcontext "github.com/avito-tech/go-transaction-manager/trm/context"
trm "github.com/avito-tech/go-transaction-manager/v2"
trmcontext "github.com/avito-tech/go-transaction-manager/v2/context"
)

// DefaultCtxGetter is the CtxGetter with settings.DefaultCtxKey.
var DefaultCtxGetter = NewCtxGetter(trmcontext.DefaultManager)

// CtxGetter gets redis.Pipeliner from trm.СtxManager by casting trm.Transaction to redis.UniversalClient.
// CtxGetter gets goredis8.Pipeliner from trm.СtxManager by casting trm.Transaction to redis.UniversalClient.
type CtxGetter struct {
ctxManager trm.СtxManager
}
Expand All @@ -22,7 +22,7 @@ func NewCtxGetter(c trm.СtxManager) *CtxGetter {
return &CtxGetter{ctxManager: c}
}

// DefaultTrOrDB returns Cmdable from context.Context or DB(redis.Cmdable) otherwise.
// DefaultTrOrDB returns Cmdable from context.Context or DB(goredis8.Cmdable) otherwise.
func (c *CtxGetter) DefaultTrOrDB(ctx context.Context, db redis.Cmdable) redis.Cmdable {
if tr := c.ctxManager.Default(ctx); tr != nil {
return c.convert(tr)
Expand All @@ -31,7 +31,7 @@ func (c *CtxGetter) DefaultTrOrDB(ctx context.Context, db redis.Cmdable) redis.C
return db
}

// TrOrDB returns Cmdable from context.Context by trm.CtxKey or DB(redis.Cmdable) otherwise.
// TrOrDB returns Cmdable from context.Context by trm.CtxKey or DB(goredis8.Cmdable) otherwise.
func (c *CtxGetter) TrOrDB(ctx context.Context, key trm.CtxKey, db redis.Cmdable) redis.Cmdable {
if tr := c.ctxManager.ByKey(ctx, key); tr != nil {
return c.convert(tr)
Expand Down
11 changes: 6 additions & 5 deletions redis/example_test.go → drivers/goredis8/example_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//go:build with_real_db
// +build with_real_db

package redis_test
package goredis8_test

import (
"context"
Expand All @@ -10,10 +10,11 @@ import (

"github.com/go-redis/redis/v8"

trmredis "github.com/avito-tech/go-transaction-manager/redis"
"github.com/avito-tech/go-transaction-manager/trm"
"github.com/avito-tech/go-transaction-manager/trm/manager"
"github.com/avito-tech/go-transaction-manager/trm/settings"
trmredis "github.com/avito-tech/go-transaction-manager/v2/drivers/goredis8/v2"

trm "github.com/avito-tech/go-transaction-manager/v2"
"github.com/avito-tech/go-transaction-manager/v2/manager"
"github.com/avito-tech/go-transaction-manager/v2/settings"
)

// Example demonstrates the implementation of the Repository pattern by trm.Manager.
Expand Down
4 changes: 2 additions & 2 deletions redis/factory.go → drivers/goredis8/factory.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package redis
package goredis8

import (
"context"

"github.com/go-redis/redis/v8"

"github.com/avito-tech/go-transaction-manager/trm"
trm "github.com/avito-tech/go-transaction-manager/v2"
)

// NewDefaultFactory creates default trm.Transaction(redis.UniversalClient).
Expand Down
10 changes: 10 additions & 0 deletions drivers/goredis8/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module github.com/avito-tech/go-transaction-manager/v2/drivers/goredis8/v2

go 1.13

require (
github.com/avito-tech/go-transaction-manager/v2 v2.0.0-rc4
github.com/go-redis/redis/v8 v8.11.5
github.com/go-redis/redismock/v8 v8.11.5
github.com/stretchr/testify v1.8.2
)
Loading