Skip to content

Commit

Permalink
chore(db): add transaction options (#1730)
Browse files Browse the repository at this point in the history
Adds the readonly option for transactions that do not write to the DB.
Adds the highest isolation level for all transactions.
  • Loading branch information
sven-urbanski-freiheit-com authored Jul 5, 2024
1 parent 15618a0 commit 743f9ee
Show file tree
Hide file tree
Showing 15 changed files with 84 additions and 87 deletions.
22 changes: 11 additions & 11 deletions pkg/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -1579,7 +1579,7 @@ func (h *DBHandler) RunCustomMigrationReleases(ctx context.Context, getAllAppsFu
span, _ := tracer.StartSpanFromContext(ctx, "RunCustomMigrationReleases")
defer span.Finish()

return h.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
return h.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
l := logger.FromContext(ctx).Sugar()
allReleasesDb, err := h.DBSelectAnyRelease(ctx, transaction)
if err != nil {
Expand Down Expand Up @@ -1641,7 +1641,7 @@ func (h *DBHandler) RunCustomMigrationDeployments(ctx context.Context, getAllDep
span, _ := tracer.StartSpanFromContext(ctx, "RunCustomMigrationDeployments")
defer span.Finish()

return h.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
return h.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
l := logger.FromContext(ctx).Sugar()
allAppsDb, err := h.DBSelectAnyDeployment(ctx, transaction)
if err != nil {
Expand Down Expand Up @@ -1699,7 +1699,7 @@ func (h *DBHandler) RunCustomMigrationEnvLocks(ctx context.Context, getAllEnvLoc
span, ctx := tracer.StartSpanFromContext(ctx, "RunCustomMigrationEnvLocks")
defer span.Finish()

return h.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
return h.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
l := logger.FromContext(ctx).Sugar()
allEnvLocksDb, err := h.DBSelectAnyActiveEnvLocks(ctx, transaction)
if err != nil {
Expand Down Expand Up @@ -1746,7 +1746,7 @@ func (h *DBHandler) RunCustomMigrationAppLocks(ctx context.Context, getAllAppLoc
span, ctx := tracer.StartSpanFromContext(ctx, "RunCustomMigrationAppLocks")
defer span.Finish()

return h.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
return h.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
l := logger.FromContext(ctx).Sugar()
allAppLocksDb, err := h.DBSelectAnyActiveAppLock(ctx, transaction)
if err != nil {
Expand Down Expand Up @@ -1793,7 +1793,7 @@ func (h *DBHandler) RunCustomMigrationTeamLocks(ctx context.Context, getAllTeamL
span, ctx := tracer.StartSpanFromContext(ctx, "RunCustomMigrationTeamLocks")
defer span.Finish()

return h.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
return h.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
l := logger.FromContext(ctx).Sugar()
allTeamLocksDb, err := h.DBSelectAnyActiveTeamLock(ctx, transaction)
if err != nil {
Expand Down Expand Up @@ -1836,7 +1836,7 @@ func (h *DBHandler) RunCustomMigrationTeamLocks(ctx context.Context, getAllTeamL
}

func (h *DBHandler) RunCustomMigrationsCommitEvents(ctx context.Context, getAllEvents GetAllEventsFun) error {
return h.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
return h.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
l := logger.FromContext(ctx).Sugar()
ev, err := h.DBSelectAnyEvent(ctx, transaction)
if err != nil {
Expand Down Expand Up @@ -1872,7 +1872,7 @@ func (h *DBHandler) RunCustomMigrationQueuedApplicationVersions(ctx context.Cont
span, ctx := tracer.StartSpanFromContext(ctx, "RunCustomMigrationQueuedApplicationVersions")
defer span.Finish()

return h.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
return h.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
l := logger.FromContext(ctx).Sugar()
allTeamLocksDb, err := h.DBSelectAnyDeploymentAttempt(ctx, transaction)
if err != nil {
Expand Down Expand Up @@ -1904,7 +1904,7 @@ func (h *DBHandler) RunCustomMigrationQueuedApplicationVersions(ctx context.Cont

// For commit_events migrations, we need some transformer to be on the database before we run their migrations.
func (h *DBHandler) RunCustomMigrationsEventSourcingLight(ctx context.Context) error {
return h.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
return h.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
span, _ := tracer.StartSpanFromContext(ctx, "RunCustomMigrationsEventSourcingLight")
defer span.Finish()
l := logger.FromContext(ctx).Sugar()
Expand Down Expand Up @@ -1965,7 +1965,7 @@ func (h *DBHandler) RunCustomMigrationAllAppsTable(ctx context.Context, getAllAp
span, ctx := tracer.StartSpanFromContext(ctx, "RunCustomMigrationAllAppsTable")
defer span.Finish()

return h.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
return h.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
l := logger.FromContext(ctx).Sugar()
allAppsDb, err := h.DBSelectAllApplications(ctx, transaction)
if err != nil {
Expand Down Expand Up @@ -2001,7 +2001,7 @@ func (h *DBHandler) RunCustomMigrationApps(ctx context.Context, getAllAppsFun Ge
span, ctx := tracer.StartSpanFromContext(ctx, "RunCustomMigrationApps")
defer span.Finish()

return h.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
return h.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
dbApp, err := h.DBSelectAnyApp(ctx, transaction)
if err != nil {
return fmt.Errorf("could not get dbApp from database - assuming the manifest repo is correct: %v", err)
Expand Down Expand Up @@ -4150,7 +4150,7 @@ func (h *DBHandler) RunCustomMigrationEnvironments(ctx context.Context, getAllEn
span, ctx := tracer.StartSpanFromContext(ctx, "RunCustomMigrationEnvironments")
defer span.Finish()

return h.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
return h.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
log := logger.FromContext(ctx).Sugar()

arbitraryAllEnvsRow, err := h.DBSelectAnyEnvironment(ctx, transaction)
Expand Down
38 changes: 19 additions & 19 deletions pkg/db/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ INSERT INTO all_apps (version , created , json) VALUES (1, '1713218400', '{"ap
if err != nil {
t.Fatal("Error establishing DB connection: ", zap.Error(err))
}
tx, err := db.DB.BeginTx(ctx, nil)
tx, err := db.BeginTransaction(ctx, false)
if err != nil {
t.Fatalf("Error creating transaction. Error: %v\n", err)
}
Expand Down Expand Up @@ -238,7 +238,7 @@ func TestCustomMigrationReleases(t *testing.T) {
ctx := context.Background()

dbHandler := SetupRepositoryTestWithDB(t)
err3 := dbHandler.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
err3 := dbHandler.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
err2 := dbHandler.RunCustomMigrationReleases(ctx, getAllApps, getAllReleases)
if err2 != nil {
return fmt.Errorf("error: %v", err2)
Expand Down Expand Up @@ -354,7 +354,7 @@ func TestCommitEvents(t *testing.T) {
t.Fatalf("Error running custom migrations for esl table. Error: %v\n", err)

}
err = db.WithTransaction(ctx, func(ctx context.Context, tx *sql.Tx) error {
err = db.WithTransaction(ctx, false, func(ctx context.Context, tx *sql.Tx) error {
if err != nil {
t.Fatalf("Error creating transaction. Error: %v\n", err)
}
Expand Down Expand Up @@ -533,7 +533,7 @@ func TestReadWriteDeployment(t *testing.T) {

dbHandler := setupDB(t)

err := dbHandler.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
err := dbHandler.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
deployment, err2 := dbHandler.DBSelectAnyDeployment(ctx, transaction)
if err2 != nil {
return err2
Expand Down Expand Up @@ -618,7 +618,7 @@ func TestDeleteEnvironmentLock(t *testing.T) {
ctx := testutil.MakeTestContext()

dbHandler := setupDB(t)
err := dbHandler.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
err := dbHandler.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
envLock, err2 := dbHandler.DBSelectEnvironmentLock(ctx, transaction, tc.Env, tc.LockID)
if err2 != nil {
return err2
Expand Down Expand Up @@ -695,7 +695,7 @@ func TestReadWriteEnvironmentLock(t *testing.T) {
ctx := testutil.MakeTestContext()

dbHandler := setupDB(t)
err := dbHandler.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
err := dbHandler.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
envLock, err2 := dbHandler.DBSelectEnvironmentLock(ctx, transaction, tc.Env, tc.LockID)
if err2 != nil {
return err2
Expand Down Expand Up @@ -770,7 +770,7 @@ func TestReadWriteApplicationLock(t *testing.T) {
ctx := testutil.MakeTestContext()

dbHandler := setupDB(t)
err := dbHandler.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
err := dbHandler.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
envLock, err2 := dbHandler.DBSelectAppLock(ctx, transaction, tc.Env, tc.AppName, tc.LockID)
if err2 != nil {
return err2
Expand Down Expand Up @@ -860,7 +860,7 @@ func TestDeleteApplicationLock(t *testing.T) {
ctx := testutil.MakeTestContext()

dbHandler := setupDB(t)
err := dbHandler.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
err := dbHandler.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
envLock, err2 := dbHandler.DBSelectEnvironmentLock(ctx, transaction, tc.Env, tc.LockID)
if err2 != nil {
return err2
Expand Down Expand Up @@ -967,7 +967,7 @@ func TestQueueApplicationVersion(t *testing.T) {
ctx := testutil.MakeTestContext()

dbHandler := setupDB(t)
err := dbHandler.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
err := dbHandler.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
for _, deployments := range tc.Deployments {
err := dbHandler.DBWriteDeploymentAttempt(ctx, transaction, deployments.Env, deployments.App, deployments.Version)
if err != nil {
Expand Down Expand Up @@ -1030,7 +1030,7 @@ func TestQueueApplicationVersionDelete(t *testing.T) {
ctx := testutil.MakeTestContext()

dbHandler := setupDB(t)
err := dbHandler.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
err := dbHandler.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
err := dbHandler.DBWriteDeploymentAttempt(ctx, transaction, tc.Env, tc.AppName, tc.Version)
if err != nil {
return err
Expand Down Expand Up @@ -1098,7 +1098,7 @@ func TestReadWriteTeamLock(t *testing.T) {
ctx := testutil.MakeTestContext()

dbHandler := setupDB(t)
err := dbHandler.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
err := dbHandler.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
envLock, err2 := dbHandler.DBSelectTeamLock(ctx, transaction, tc.Env, tc.TeamName, tc.LockID)
if err2 != nil {
return err2
Expand Down Expand Up @@ -1188,7 +1188,7 @@ func TestDeleteTeamLock(t *testing.T) {
ctx := testutil.MakeTestContext()

dbHandler := setupDB(t)
err := dbHandler.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
err := dbHandler.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
envLock, err2 := dbHandler.DBSelectTeamLock(ctx, transaction, tc.Env, tc.TeamName, tc.LockID)
if err2 != nil {
return err2
Expand Down Expand Up @@ -1277,7 +1277,7 @@ func TestDeleteRelease(t *testing.T) {
ctx := testutil.MakeTestContext()

dbHandler := setupDB(t)
err := dbHandler.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
err := dbHandler.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
err2 := dbHandler.DBInsertRelease(ctx, transaction, tc.toInsert, tc.toInsert.EslId-1)
if err2 != nil {
return err2
Expand Down Expand Up @@ -1453,7 +1453,7 @@ func TestReadWriteEnvironment(t *testing.T) {
dbHandler := setupDB(t)

for _, envToWrite := range tc.EnvsToWrite {
err := dbHandler.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
err := dbHandler.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
err := dbHandler.DBWriteEnvironment(ctx, transaction, envToWrite.EnvironmentName, envToWrite.EnvironmentConfig)
if err != nil {
return fmt.Errorf("error while writing environment, error: %w", err)
Expand All @@ -1465,7 +1465,7 @@ func TestReadWriteEnvironment(t *testing.T) {
}
}

envEntry, err := WithTransactionT(dbHandler, ctx, func(ctx context.Context, transaction *sql.Tx) (*DBEnvironment, error) {
envEntry, err := WithTransactionT(dbHandler, ctx, true, func(ctx context.Context, transaction *sql.Tx) (*DBEnvironment, error) {
envEntry, err := dbHandler.DBSelectEnvironment(ctx, transaction, tc.EnvToQuery)
if err != nil {
return nil, fmt.Errorf("error while selecting environment entry, error: %w", err)
Expand Down Expand Up @@ -1557,7 +1557,7 @@ func TestReadWriteEslEvent(t *testing.T) {
t.Parallel()
ctx := testutil.MakeTestContext()
dbHandler := setupDB(t)
err := dbHandler.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
err := dbHandler.WithTransaction(ctx, true, func(ctx context.Context, transaction *sql.Tx) error {
err := dbHandler.DBWriteEslEventInternal(ctx, tc.EventType, transaction, tc.EventData, tc.EventMetadata)
if err != nil {
return err
Expand Down Expand Up @@ -1621,7 +1621,7 @@ func TestReadWriteAllEnvironments(t *testing.T) {
dbHandler := setupDB(t)

for _, allEnvs := range tc.AllEnvsToWrite {
err := dbHandler.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
err := dbHandler.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
err := dbHandler.DBWriteAllEnvironments(ctx, transaction, allEnvs)
if err != nil {
return fmt.Errorf("error while writing environment, error: %w", err)
Expand All @@ -1633,7 +1633,7 @@ func TestReadWriteAllEnvironments(t *testing.T) {
}
}

allEnvsEntry, err := WithTransactionT(dbHandler, ctx, func(ctx context.Context, transaction *sql.Tx) (*DBAllEnvironments, error) {
allEnvsEntry, err := WithTransactionT(dbHandler, ctx, true, func(ctx context.Context, transaction *sql.Tx) (*DBAllEnvironments, error) {
allEnvsEntry, err := dbHandler.DBSelectAllEnvironments(ctx, transaction)
if err != nil {
return nil, fmt.Errorf("error while selecting environment entry, error: %w", err)
Expand Down Expand Up @@ -1790,7 +1790,7 @@ func TestReadReleasesByApp(t *testing.T) {
ctx := testutil.MakeTestContext()
dbHandler := setupDB(t)

err := dbHandler.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
err := dbHandler.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
for _, release := range tc.Releases {
err := dbHandler.DBInsertRelease(ctx, transaction, release, release.EslId-1)
if err != nil {
Expand Down
31 changes: 18 additions & 13 deletions pkg/db/transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ type DBFunctionMultipleEntriesT[T any] func(ctx context.Context, transaction *sq

// WithTransaction opens a transaction, runs `f` and then calls either Commit or Rollback.
// Use this if the only thing to return from `f` is an error.
func (h *DBHandler) WithTransaction(ctx context.Context, f DBFunction) error {
_, err := WithTransactionT(h, ctx, func(ctx context.Context, transaction *sql.Tx) (*interface{}, error) {
func (h *DBHandler) WithTransaction(ctx context.Context, readonly bool, f DBFunction) error {
_, err := WithTransactionT(h, ctx, readonly, func(ctx context.Context, transaction *sql.Tx) (*interface{}, error) {
err2 := f(ctx, transaction)
if err2 != nil {
return nil, err2
Expand All @@ -43,8 +43,8 @@ func (h *DBHandler) WithTransaction(ctx context.Context, f DBFunction) error {
}

// WithTransactionT is the same as WithTransaction, but you can also return data, not just the error.
func WithTransactionT[T any](h *DBHandler, ctx context.Context, f DBFunctionT[T]) (*T, error) {
res, err := WithTransactionMultipleEntriesT(h, ctx, func(ctx context.Context, transaction *sql.Tx) ([]T, error) {
func WithTransactionT[T any](h *DBHandler, ctx context.Context, readonly bool, f DBFunctionT[T]) (*T, error) {
res, err := WithTransactionMultipleEntriesT(h, ctx, readonly, func(ctx context.Context, transaction *sql.Tx) ([]T, error) {
fRes, err2 := f(ctx, transaction)
if err2 != nil {
return nil, err2
Expand All @@ -61,17 +61,17 @@ func WithTransactionT[T any](h *DBHandler, ctx context.Context, f DBFunctionT[T]
}

// WithTransactionMultipleEntriesT is the same as WithTransaction, but you can also return and array of data, not just the error.
func WithTransactionMultipleEntriesT[T any](h *DBHandler, ctx context.Context, f DBFunctionMultipleEntriesT[T]) ([]T, error) {
func WithTransactionMultipleEntriesT[T any](h *DBHandler, ctx context.Context, readonly bool, f DBFunctionMultipleEntriesT[T]) ([]T, error) {
span, ctx := tracer.StartSpanFromContext(ctx, "DBTransaction")
defer span.Finish()
onError := func(e error) {
onError := func(e error) ([]T, error) {
span.Finish(tracer.WithError(e))
return nil, e
}

tx, err := h.DB.BeginTx(ctx, nil)
tx, err := h.BeginTransaction(ctx, readonly)
if err != nil {
onError(err)
return nil, err
return onError(err)
}
defer func(tx *sql.Tx) {
_ = tx.Rollback()
Expand All @@ -81,13 +81,18 @@ func WithTransactionMultipleEntriesT[T any](h *DBHandler, ctx context.Context, f

result, err := f(ctx, tx)
if err != nil {
onError(err)
return nil, err
return onError(err)
}
err = tx.Commit()
if err != nil {
onError(err)
return nil, err
return onError(err)
}
return result, nil
}

func (h *DBHandler) BeginTransaction(ctx context.Context, readonly bool) (*sql.Tx, error) {
return h.DB.BeginTx(ctx, &sql.TxOptions{
Isolation: sql.LevelLinearizable,
ReadOnly: readonly,
})
}
27 changes: 9 additions & 18 deletions services/cd-service/pkg/repository/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ func New2(ctx context.Context, cfg RepositoryConfig) (Repository, setup.Backgrou

// Check configuration for errors and abort early if any:
if state.DBHandler.ShouldUseOtherTables() {
_, err = db.WithTransactionT(state.DBHandler, ctx, func(ctx context.Context, transaction *sql.Tx) (*map[string]config.EnvironmentConfig, error) {
_, err = db.WithTransactionT(state.DBHandler, ctx, false, func(ctx context.Context, transaction *sql.Tx) (*map[string]config.EnvironmentConfig, error) {
ret, err := state.GetEnvironmentConfigsAndValidate(ctx, transaction)
return &ret, err
})
Expand Down Expand Up @@ -541,7 +541,7 @@ func (r *repository) applyTransformerBatches(transformerBatches []transformerBat
var txErr error
e := transformerBatches[i]
if r.DB.ShouldUseEslTable() {
transaction, txErr = r.DB.DB.BeginTx(e.ctx, nil)
transaction, txErr = r.DB.BeginTransaction(e.ctx, false)
if txErr != nil {
e.finish(txErr)
transformerBatches = append(transformerBatches[:i], transformerBatches[i+1:]...)
Expand Down Expand Up @@ -781,23 +781,14 @@ func (r *repository) ProcessQueueOnce(ctx context.Context, e transformerBatch, c
}

func UpdateDatadogMetricsDB(ctx context.Context, state *State, r Repository, changes *TransformerResult, now time.Time) error {
var transaction *sql.Tx
var txErr error
repo := r.(*repository)
transaction, txErr = repo.DB.DB.BeginTx(ctx, nil)
if txErr != nil {
return txErr
}
defer func(tx *sql.Tx) {
_ = tx.Rollback()
}(transaction)

ddError := UpdateDatadogMetrics(ctx, transaction, state, r, changes, now)
if ddError != nil {
return ddError
}

err := transaction.Commit()
err := repo.DB.WithTransaction(ctx, true, func(ctx context.Context, transaction *sql.Tx) error {
ddError := UpdateDatadogMetrics(ctx, transaction, state, r, changes, now)
if ddError != nil {
return ddError
}
return nil
})
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion services/cd-service/pkg/repository/transformer.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ func RegularlySendDatadogMetrics(repo Repository, interval time.Duration, callBa
func GetRepositoryStateAndUpdateMetrics(ctx context.Context, repo Repository) {
s := repo.State()
if s.DBHandler.ShouldUseOtherTables() {
err := s.DBHandler.WithTransaction(ctx, func(ctx context.Context, transaction *sql.Tx) error {
err := s.DBHandler.WithTransaction(ctx, true, func(ctx context.Context, transaction *sql.Tx) error {
if err := UpdateDatadogMetrics(ctx, transaction, s, repo, nil, time.Now()); err != nil {
return err
}
Expand Down
Loading

0 comments on commit 743f9ee

Please sign in to comment.