Skip to content

Improve APIs for using transactions #1223

@belak

Description

@belak

I've been mocking up some changes to the generated interfaces to make using transactions easier, but I wanted to get opinions before I spend the time implementing it. The below snippets are using pgx, but it should translate similarly to database/sql as well.

// Shared interface between DB and Tx. This is unchanged from the current implementation.
interface DBTX {
	Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
	Query(context.Context, string, ...interface{}) (pgx.Rows, error)
	QueryRow(context.Context, string, ...interface{}) pgx.Row
}

// DB is roughly equivalent to the pgx.Conn, but Begin is pgx.Conn's BeginEx, and
// I based BeginFunc on BoltDB's transactions because it provides a fairly ergonomic
// API once you get used to it.
// https://github.com/etcd-io/bbolt#transactions
interface DB {
	DBTX

	// Begin starts a transaction - be careful with this. You must either Commit or
	// Rollback the transaction for the sake of your database.
	Begin(ctx context.Context) (Tx, error)

	// Begin starts a transaction and executes f. If f does not return an err, the transaction will be
	// committed. If it does, then the transaction will be rolled back. BeginFunc returns the inner
	// returned error.
	BeginFunc(ctx context.Context, f (context.Context, Tx), error) error
}

interface Tx {
	DBTX
	CommitEx(ctx context.Context) error
	RollbackEx(ctx context.Context) error
}

Here is the main problem I've been running into - before I started switching to sqlc, I attached all the generated methods to the DBTX, but because of the possibility of using prepared queries with database/sql, this is not possible - in sqlc there is a concrete Queries type which all of them are attached to. There could be some unexported generated types, but that seems less than ideal. Do you have any ideas to solve that? Is this even worth pursuing? Are there better ways/APIs to make transactions easier to use?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions