Skip to content

Instantly share code, notes, and snippets.

@alexrios
Created November 13, 2020 02:26
Show Gist options
  • Save alexrios/8665c859d63bfe302f8226a43871dce0 to your computer and use it in GitHub Desktop.
Save alexrios/8665c859d63bfe302f8226a43871dce0 to your computer and use it in GitHub Desktop.
Postgres advisory locks with Go
package database
import (
"context"
"errors"
"fmt"
)
import "github.com/jackc/pgx/v4"
// mutex is an implementation of the Mutexer interface
type pgxMutex struct {
conn *pgx.Conn
}
// newMutex returns a new Mutex
func NewPgxMutex(db *pgx.Conn) *pgxMutex {
return &pgxMutex{conn: db}
}
// Lock set a mutex for database write
func (m *pgxMutex) Lock(ctx context.Context, lockID int) error {
var result bool
err := m.conn.QueryRow(ctx, fmt.Sprintf("SELECT pg_try_advisory_lock(%d)", lockID)).Scan(&result)
if err != nil {
return err
}
if !result {
return errors.New("database mutex is already taken")
}
return nil
}
// Unlock remove the current database mutex
func (m *pgxMutex) Unlock(ctx context.Context, lockID int) error {
var result bool
err := m.conn.QueryRow(ctx, fmt.Sprintf("SELECT pg_advisory_unlock(%d)", lockID)).Scan(&result)
if err != nil {
return err
}
if !result {
return errors.New("unable to release database mutex")
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment