snapshot of https://github.com/sqlc-dev/sqlc.git (main, 2026-09-16; blobs > 131072B omitted)
Some checks failed
kotlin / test (push) Has been skipped
python / test (push) Has been skipped
typescript / test (push) Has been skipped
go / build darwin/amd64 (push) Has been cancelled
go / build linux/amd64 (push) Has been cancelled
go / build windows/amd64 (push) Has been cancelled
go / build darwin/arm64 (push) Has been cancelled
go / build linux/arm64 (push) Has been cancelled
go / build windows/arm64 (push) Has been cancelled
go / test (push) Has been cancelled
go / vuln_check (push) Has been cancelled
Some checks failed
kotlin / test (push) Has been skipped
python / test (push) Has been skipped
typescript / test (push) Has been skipped
go / build darwin/amd64 (push) Has been cancelled
go / build linux/amd64 (push) Has been cancelled
go / build windows/amd64 (push) Has been cancelled
go / build darwin/arm64 (push) Has been cancelled
go / build linux/arm64 (push) Has been cancelled
go / build windows/arm64 (push) Has been cancelled
go / test (push) Has been cancelled
go / vuln_check (push) Has been cancelled
This commit is contained in:
101
docs/howto/transactions.md
Normal file
101
docs/howto/transactions.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# Using transactions
|
||||
In the code generated by sqlc, the `WithTx` method allows a `Queries` instance to be associated with a transaction.
|
||||
|
||||
For example, with the following SQL structure:
|
||||
|
||||
`schema.sql`:
|
||||
```sql
|
||||
CREATE TABLE records (
|
||||
id SERIAL PRIMARY KEY,
|
||||
counter INT NOT NULL
|
||||
);
|
||||
```
|
||||
|
||||
`query.sql`
|
||||
```sql
|
||||
-- name: GetRecord :one
|
||||
SELECT * FROM records
|
||||
WHERE id = $1;
|
||||
|
||||
-- name: UpdateRecord :exec
|
||||
UPDATE records SET counter = $2
|
||||
WHERE id = $1;
|
||||
```
|
||||
|
||||
And the generated code from sqlc in `db.go`:
|
||||
```go
|
||||
package tutorial
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
)
|
||||
|
||||
type DBTX interface {
|
||||
ExecContext(context.Context, string, ...any) (sql.Result, error)
|
||||
PrepareContext(context.Context, string) (*sql.Stmt, error)
|
||||
QueryContext(context.Context, string, ...any) (*sql.Rows, error)
|
||||
QueryRowContext(context.Context, string, ...any) *sql.Row
|
||||
}
|
||||
|
||||
func New(db DBTX) *Queries {
|
||||
return &Queries{db: db}
|
||||
}
|
||||
|
||||
type Queries struct {
|
||||
db DBTX
|
||||
}
|
||||
|
||||
func (q *Queries) WithTx(tx *sql.Tx) *Queries {
|
||||
return &Queries{
|
||||
db: tx,
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
You'd use it like this:
|
||||
|
||||
```go
|
||||
// Using `github/lib/pq` as the driver.
|
||||
func bumpCounter(ctx context.Context, db *sql.DB, queries *tutorial.Queries, id int32) error {
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
qtx := queries.WithTx(tx)
|
||||
r, err := qtx.GetRecord(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := qtx.UpdateRecord(ctx, tutorial.UpdateRecordParams{
|
||||
ID: r.ID,
|
||||
Counter: r.Counter + 1,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// Using `github.com/jackc/pgx/v5` as the driver.
|
||||
func bumpCounter(ctx context.Context, db *pgx.Conn, queries *tutorial.Queries, id int32) error {
|
||||
tx, err := db.Begin(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
qtx := queries.WithTx(tx)
|
||||
r, err := qtx.GetRecord(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := qtx.UpdateRecord(ctx, tutorial.UpdateRecordParams{
|
||||
ID: r.ID,
|
||||
Counter: r.Counter + 1,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Commit(ctx)
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user