tx, err := db.BeginTx(ctx, nil) if err != nil { return errors.Wrap(err, "starting transaction") } defer func() { if err != nil { _ = tx.Rollback() return } err = tx.Commit() }() waitCtx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() txOpts := &sql.TxOptions{Isolation: sql.LevelSerializable} tx, err = migration.LimitedTx(waitCtx, tx, txOpts) if err != nil { return errors.Wrap(err, "starting limited tx") } _, err = tx.Exec("INSERT INTO foo (bar) VALUES (?)", "baz") if err != nil { return errors.Wrap(err, "executing insert") }
func WithTimeout(f func(ctx context.Context, tx migration.LimitedTx) error) error { ctx := context.Background() db, err := sql.Open("postgres", "") if err != nil { return err } defer db.Close() ctx, cancel := context.WithTimeout(ctx, 2*time.Second) defer cancel() tx, err := db.BeginTx(ctx, nil) if err != nil { return err } defer func() { if err != nil { _ = tx.Rollback() return } err = tx.Commit() }() txOpts := &sql.TxOptions{Isolation: sql.LevelSerializable} tx, err = migration.LimitedTx(ctx, tx, txOpts) if err != nil { return errors.Wrap(err, "starting limited tx") } return f(ctx, tx) }This code defines a method "WithTimeout" that takes a function as a parameter and creates a transaction and executes the function within a limited time using the LimitedTx module. The waiting time is set to 2 seconds. If the transaction exceeds the specified limit, it will be rolled back.