Open hhstore opened 5 years ago
- 注意: TryLock(), 返回一个 unlock() 方法, 等待后续执行用.
- TryLock() 内部实现, 启动一个 go 例程, 用 select 监听返回.
func (l *locker) TryLock(doc object.Interface, t time.Duration) (func() error, error) {
key, err := getKey(doc)
if err != nil {
return nil, err
}
ch := make(chan error)
conn := l.rp.Get()
defer conn.Close()
go func(c redis.Conn) {
_, err = redis.String(c.Do("SET", key, "NX"))
select {
case ch <- err:
default:
}
}(conn)
select {
case err = <-ch:
if err != nil {
return nil, err
}
return func() error { return l.unlock(key) }, nil
case <-time.After(t):
return nil, ErrTimeout
}
}
func (l *locker) unlock(key string) error {
conn := l.rp.Get()
_, err := conn.Do("DEL", key)
conn.Close()
return err
}
- product 服务, 对 get 操作, db 查询之前加锁.
// Get
func (s *productService) Get(ctx context.Context, req *productpb.GetRequest) (*productpb.Product, error) {
if err := validation.Validate(req); err != nil {
return nil, err
}
p := &product{
Product: productpb.Product{
Id: req.Id,
},
}
unlock, err := locker.Handler().TryLock(p, time.Second)
if err != nil {
return nil, err
}
defer unlock()
if err := storage.Handler().One(p); err != nil {
return nil, err
}
// get products skus
skus, err := sku.Service().ProductData(ctx, &sku.ProductDataReq{Id: p.GetId()})
if err != nil {
return nil, err
}
p.Skus = skus
return &p.Product, nil
}
[digota/storage/handlers/mongo/mongo.go]()
基于 mongo 的 增删改查
package mongo
import (
....
"github.com/digota/digota/storage/object"
....
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
// mongodb 对象:
type handler struct {
client *mgo.Session // db 对象
dailInfo *mgo.DialInfo // db 连接
database string
}
// Insert
func (h *handler) Insert(obj object.Interface) error {
s := h.client.New()
defer s.Close()
if v, ok := obj.(object.IdSetter); ok {
v.SetId(uuid.NewV4().String())
}
if v, ok := obj.(object.TimeTracker); ok {
v.SetCreated(time.Now().Unix())
v.SetUpdated(time.Now().Unix())
}
if err := s.DB(h.database).C(obj.GetNamespace()).Insert(obj); err != nil {
return status.Error(codes.Internal, err.Error())
}
return nil
}
Related:
129 : annotated:
pipe