golang优雅代码【lock实现】
- 1.局部锁
- 1.1 具体实现方式
本文代码风格来源参考
database/sql
包
1.局部锁
database/sql
源码中使用 withLock(dc, func(){...})
方法实现局部锁,完美利用了 golang
的 defer
关键字对 入参dc
进行加锁解锁,感觉实现很优雅
func (db *DB) queryDC(ctx, txctx context.Context, dc *driverConn, releaseConn func(error), query string, args []any) (*Rows, error) {queryerCtx, ok := dc.ci.(driver.QueryerContext)...if ok {...withLock(dc, func() {// do something ... })...}...return rows, nil
}
1.1 具体实现方式
- 首先定义
driverConn
封装sync.Mutex
,实现sync.Locker
接口
type driverConn struct {db *DB...sync.Mutex // guards following
}
- 定义函数
withLock
,接收sync.Locker
,func()
入参,在内部实现获取/释放锁,并执行对应函数
// withLock runs while holding lk.
func withLock(lk sync.Locker, fn func()) {lk.Lock()defer lk.Unlock() // in case fn panicsfn()
}
- 使用该方式实现锁
func (db *DB) queryDC(ctx context.Context, dc *driverConn) (*Rows, error) {...// 获取&释放锁withLock(dc, func() {// do something ... })...return rows, nil
}
- 对比普通方式(非常容易忘记释放锁,并且还要考虑errror)
func (db *DB) queryDC(ctx context.Context, dc *driverConn) (*Rows, error) {...// 获取&释放锁dc.Lock()// do something ... dc.Unlock()...return rows, nil
}