背景
分布式锁有很多中实现方式,此文针对的是,在加锁后是针对mysql做相应操作
原理简介
get_lock是会话中有效的(会话结束,锁释放),只要我们后续的操作使用同一个链接,那么可以保证后续的操作是都是在在锁中
release_lock则是释放锁
示意代码
package main
import (
"context"
"database/sql"
"fmt"
)
func main() {
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?%s",
"root",
"password",
"127.0.0.1",
3306,
"test",
)
db, err := sql.Open("mysql", dsn)
if err != nil {
panic(err)
}
ctx := context.Background()
conn, err := db.Conn(ctx)
if err != nil {
panic(err)
}
var success bool
if err:=conn.QueryRowContext(ctx,"select get_lock(?,?)","lock",1).Scan(&success);err!=nil{
panic(err)
}
if !success{
panic("conflict")
}
defer func(){conn.QueryRowContext(ctx,"select release_lock(?)","lock").Scan(&success)}()
tx, err := conn.BeginTx(ctx, nil)
if err != nil {
panic(err)
}
defer tx.Rollback()
_,err=tx.ExecContext(ctx,"insert into tets(name,password) values(?,?)","test","test")
if err!=nil{
panic(err)
}
if err:=tx.Commit();err!=nil{
panic(err)
}
}