(八)setnx实现分布式锁

distribute_lock.go

package lock

import (
	"errors"
	"fmt"
	"github.com/gomodule/redigo/redis"
)

type DistributeLock struct {
	Key   string
	Value string

	RedisAddress string
}

func NewDistributeLock(key string, value string, redisAddress string) *DistributeLock {
	return &DistributeLock{Key: key, Value: value, RedisAddress: redisAddress}
}

func (dl *DistributeLock) Lock() error {
	c, err := redis.Dial("tcp", dl.RedisAddress)
	if err != nil {
		return err
	}
	defer c.Close()

	res, err := redis.Int(c.Do("setnx", dl.Key, dl.Value))
	if err != nil {
		return err
	}
	if res != 1 {
		return errors.New("lock failed")
	}
	return nil
}

func (dl *DistributeLock) UnLock() error {
	c, err := redis.Dial("tcp", dl.RedisAddress)
	if err != nil {
		return err
	}
	defer c.Close()

	res, err := redis.Int(c.Do("del", dl.Key))
	if err != nil {
		return err
	}
	if res != 1 {
		return errors.New("unlock failed")
	}
	return nil
}

func (dl *DistributeLock) GetLock() error {
	c, err := redis.Dial("tcp", dl.RedisAddress)
	if err != nil {
		return err
	}
	defer c.Close()

	result, err := redis.String(c.Do("GET", dl.Key))
	if err != nil {
		return err
	}
	fmt.Printf("key: %v, value: %v\n", dl.Key, result)
	return nil
}

disribute_lock_test.go

package lock

import (
	"fmt"
	"testing"
)

func TestDistributeLock_Lock(t *testing.T) {
	dl := NewDistributeLock("lock.bluetool", "uuid", "10.1.64.80:6379")
	err := dl.Lock()
	if err != nil {
		fmt.Printf("lock failed")
		return
	}
	defer dl.UnLock()

	// do something
	dl.GetLock()
}

posted @ 2019-03-26 15:30  yvhqbat  阅读(766)  评论(0编辑  收藏  举报