Help us shape the future of Go! Take the 2026 Go Developer Survey

sequence

package
v0.26.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 25, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

README

Transaction-bound scoped sequences

Reserve(ctx, tx, Request) reserves exact numeric values inside the supplied transaction for a physical table/column and typed scope tuple. It supports numeric columns which are not identity/primary-key fields. It never writes application rows, completes a transaction, or exposes a process-local counter.

values, err := sequence.Reserve(ctx, tx, sequence.Request{
    Dialect: "sqlite", Table: "message", Column: "sequence",
    Scope: []sequence.Scope{{Column: "turn_id", Value: turnID}},
    Count: 2, Supplied: []int64{3},
})

With stored turn maximum 2, this returns 4 and 5. Other turns have independent counters. Supplied values are skipped, not rewritten. Pass the complete batch's supplied values on every reservation; count zero performs no allocation.

The ledger sqlx_scoped_sequences belongs to the same schema as the source. SQLite can create it within its transaction and takes write intent before reads. MySQL uses an InnoDB counter row lock; call Provision(ctx, db, "mysql") outside business transactions first, because MySQL DDL implicitly commits. Qualified source tables require the ledger in that schema. Unsupported dialects fail.

Counters advance in the caller transaction, so rollback restores reservations. Keep the transaction open through the corresponding source writes. Scope values are bound parameters; identifiers are parsed/quoted. Scope fields must be non-null strings, booleans or integers. Use stable field types for one partition. Collision proves a generated tuple/value collision while rejecting a present primary identity; it is intended for framework-controlled rollback/replay.

Live MySQL tests use SQLX_SCOPED_MYSQL_DSN, which must name an isolated test schema: they provision the ledger and create/drop fixture tables. SQLite tests and live MySQL tests include genuinely independent database connections.

Documentation

Overview

Package sequence owns transaction-bound scoped numeric allocation.

Index

Constants

View Source
const LedgerTable = "sqlx_scoped_sequences"

Variables

This section is empty.

Functions

func Collision

func Collision(ctx context.Context, db *sql.DB, dialect, table, column string, scope []Scope, value int64, identity []Scope) (bool, error)

Collision verifies that a generated scope/value was taken by another row and that the requested row identity is still absent. This prevents replay from turning a concurrent primary-key insert into an unintended UPDATE.

func Provision

func Provision(ctx context.Context, db *sql.DB, dialect string) error

Provision creates the counter table. MySQL callers provision before starting business transactions: DDL must never implicitly commit a caller transaction.

func Reserve

func Reserve(ctx context.Context, tx *sql.Tx, r Request) ([]int64, error)

Reserve locks and advances one scope in the supplied transaction. It never commits/rolls back it, executes source INSERTs, or mutates application records. SQLite's first statement is a write, before any MAX/snapshot read.

Types

type Request

type Request struct {
	Dialect, Table, Column string
	Scope                  []Scope
	Count                  int
	Supplied               []int64
}

Request selects one independent numeric sequence. Supplied values from the complete invocation must be passed before allocating any generated values.

type Scope

type Scope struct {
	Column string
	Value  any
}

Scope binds physical columns to values. Values are always SQL parameters.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL