Created
November 13, 2020 02:26
-
-
Save alexrios/8665c859d63bfe302f8226a43871dce0 to your computer and use it in GitHub Desktop.
Postgres advisory locks with Go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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