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

advisorylock

package
v1.149.0 Latest Latest
Warning

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

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

Documentation

Overview

Package advisorylock holds the platform's PostgreSQL session advisory locks on one database session per process (#2169).

An advisory lock belongs to the session that took it, so a lock held for a background pass used to pin a pooled connection of its own for the whole pass, while the pass drew its queries from the same pool. Each locked loop added one more pinned connection. With four loops locked on a pool of five, the passes waited on the pool for their own queries, never finished, never released their locks, and starved every request on the replica.

PostgreSQL lets one session hold any number of advisory locks, so every try-lock the process takes goes onto one Session: however many loops hold a lock, together they pin one connection, and the session goes back to the pool when the last lock is released. The pass itself runs on the pool, never on the lock's session.

A session lock is reentrant in PostgreSQL: the session holding a key is granted it again. A Session therefore refuses a key the process already holds, so two goroutines of one process exclude each other as two replicas do.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Try

func Try(ctx context.Context, db *sql.DB, key Key) (release func(), ok bool, err error)

Try takes key on db's lock session; see Session.Try.

Types

type Key

type Key struct {
	// contains filtered or unexported fields
}

Key is one advisory lock: a single bigint, or the two-integer form, which PostgreSQL keeps in a key space of its own.

func ID

func ID(id int64) Key

ID is the lock keyed by one bigint.

func Pair

func Pair(space, n int32) Key

Pair is the lock keyed by two integers.

type Session

type Session struct {
	// contains filtered or unexported fields
}

Session is the one database session a process takes its advisory locks on. It is safe for concurrent use.

func For

func For(db *sql.DB) *Session

For is the process's lock session over db.

func New

func New(db *sql.DB) *Session

New builds a Session over db. Production code uses For, which keeps one per database handle; New is for a test that stands two replicas on one.

func (*Session) Held

func (s *Session) Held(ctx context.Context, key Key) (bool, error)

Held reports whether any session, this process's included, holds key.

func (*Session) Try

func (s *Session) Try(ctx context.Context, key Key) (release func(), ok bool, err error)

Try takes key without waiting. ok is false when another session holds it or this process already does. release gives it back and is safe to call more than once; it does nothing when the session ended in the meantime, since that released the lock.

Jump to

Keyboard shortcuts

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