lock

package module
v0.0.4 Latest Latest
Warning

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

Go to latest
Published: Apr 27, 2022 License: MIT Imports: 9 Imported by: 0

README

mysql-lock

a simple distributed lock based on mysql

Usage

go get github.com/vearne/mysql-lock

mysql-lock uses 2 methods to build MySQL's distributed lock

  • Method 1: row lock initialization
mlock.NewRowLockWithDSN()
mlock.NewRowLockWithConn()
  • Method 2: set flag initialization
mlock.NewCounterLockWithDSN()
mlock.NewCounterLockWithConn()

Notice

Distributed locks based on mysql are not rigorous.

  • Method 1: For example, at t1, A holds the lock, and B waits for the lock. At t2, the network between A and MySQL is abnormal. MySQL actively releases the lock imposed by A (rolling back the transaction that A has not committed), and B adds the lock. At this time, A will think that it owns the lock; B will also think that it holds the lock. The distributed lock actually fails.

  • Method 2: For example, at time t1, A holds the lock and B waits for the lock. At time t2, A suddenly crashes, causing the lock to not be released normally. then B will never be able to acquire the lock.

mysql-lock will create the table. Method 1 creates the table _lock_store. Method 2 creates the table _lock_counter. So mysql-lock needs CREATE permission. Or you can use doc/schema.sql to create the table yourself.

Example

package main

import (
	mlock "github.com/vearne/mysql-lock"
	"log"
	"time"
)

func main() {
	debug := false
	dsn := "tc_user:20C462C9C614@tcp(127.0.0.1:3306)/xxx?charset=utf8&loc=Asia%2FShanghai&parseTime=true"

	var locker mlock.MySQLLockItf
	locker = mlock.NewRowLockWithDSN(dsn, debug)
	//locker = mlock.NewCounterLockWithDSN(dsn, debug)

	// init() can be executed multiple times
	locker.Init([]string{"lock1", "lock2"})

	beginTime := time.Now()
	// max wait for 5 secs
	err := locker.Acquire("lock1", 5*time.Second)
	if err != nil {
		log.Println("can't acquire lock", err)
		log.Println(time.Since(beginTime))
		return
	}

	log.Println("got lock1")
	log.Println(time.Since(beginTime))
	time.Sleep(8 * time.Second)
	locker.Release("lock1")
	log.Println("release lock1")
}

Documentation

Index

Constants

View Source
const (
	LockStatusOpen   = 0
	LockStatusClosed = 1
)

Variables

This section is empty.

Functions

func InitMySQLWithConn added in v0.0.4

func InitMySQLWithConn(sqlDB *sql.DB) *gorm.DB

initialize *gorm.DB with an existing database connection

func InitMySQLWithDSN added in v0.0.4

func InitMySQLWithDSN(dsn string, debug bool) *gorm.DB

initialize *gorm.DB with dsn

Types

type LockCounter added in v0.0.4

type LockCounter struct {
	Name       string    `gorm:"column:name;size:100;index:uni_name,unique" json:"name"`
	Owner      string    `gorm:"column:owner;size:100" json:"owner"`
	Counter    uint64    `gorm:"column:counter" json:"counter"`
	CreatedAt  time.Time `gorm:"column:created_at" json:"createdAt"`
	ModifiedAt time.Time `gorm:"column:modified_at" json:"modifiedAt"`
	// other
	ID int `gorm:"column:id" json:"id"`
}

func (LockCounter) TableName added in v0.0.4

func (LockCounter) TableName() string

type LockStore

type LockStore struct {
	Name      string    `gorm:"column:name;size:100;index:uni_name,unique" json:"name"`
	CreatedAt time.Time `gorm:"column:created_at" json:"createdAt"`
	// other
	ID int `gorm:"column:id" json:"id"`
}

func (LockStore) TableName

func (LockStore) TableName() string

type MySQCounterLock added in v0.0.4

type MySQCounterLock struct {
	MySQLClient *gorm.DB
	ClientID    string
}

func (*MySQCounterLock) Acquire added in v0.0.4

func (l *MySQCounterLock) Acquire(lockName string, wait time.Duration) error

Lock :If the lock cannot be obtained, it will keep blocking wait: < 0 no wait

func (*MySQCounterLock) Init added in v0.0.4

func (l *MySQCounterLock) Init(lockNameList []string)

Init :Create tables

func (*MySQCounterLock) Release added in v0.0.4

func (l *MySQCounterLock) Release(lockName string) error

type MySQLLockItf added in v0.0.4

type MySQLLockItf interface {
	Init(lockNameList []string)
	Acquire(lockName string, wait time.Duration) error
	Release(lockName string) error
}

func NewCounterLockWithConn added in v0.0.4

func NewCounterLockWithConn(db *sql.DB) MySQLLockItf

func NewCounterLockWithDSN added in v0.0.4

func NewCounterLockWithDSN(dsn string, debug bool) MySQLLockItf

func NewRowLockWithConn added in v0.0.4

func NewRowLockWithConn(db *sql.DB) MySQLLockItf

func NewRowLockWithDSN added in v0.0.4

func NewRowLockWithDSN(dsn string, debug bool) MySQLLockItf

type MySQRowLLock added in v0.0.4

type MySQRowLLock struct {
	sync.Mutex
	MySQLClient *gorm.DB
	TXMap       map[string]*gorm.DB
}

func (*MySQRowLLock) Acquire added in v0.0.4

func (l *MySQRowLLock) Acquire(lockName string, wait time.Duration) error

Lock :If the lock cannot be obtained, it will keep blocking

func (*MySQRowLLock) Init added in v0.0.4

func (l *MySQRowLLock) Init(lockNameList []string)

Init :Create tables Create row record

func (*MySQRowLLock) Release added in v0.0.4

func (l *MySQRowLLock) Release(lockName string) error

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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