您的位置 首页 golang

Redis optimistic lock with golang demo

redis 事务处理命令

  • MULTI:开启一个事务
  • EXEC:事务执行,将一次性执行事务内的所有命令
  • DISCARD:取消事务

使用 WATCH+MULTI 的方式来实现乐观锁

WATCH:监控一个或多个键,如果事务执行前某个键发生了改动,那么事务也会被打断
UNWATCH:取消 WATCH 命令对所有键的监视

使用go-redis package模拟用户抢票的流程

  • 开启多个goroutine模拟并发抢票
  • go-redis TxPipelined 执行事务
  • go-redis client.Watch 监控某个键
package mainimport (    "errors"    "fmt"    "sync"    "github.com/go-redis/redis/v7")func main() {    client := redis.NewClient(&redis.Options{        Addr:     "localhost:6379",        Password: "", // no password set        DB:       0,  // use default DB    })    key := "ticket_count"    client.Set(key, "5", 0).Err()    val, _ := client.Get(key).Result()    fmt.Println("current ticket_count key val: ", val)    getTicket(client, key)}func runTx(key string, id int) func(tx *redis.Tx) error {    txf := func(tx *redis.Tx) error {        n, err := tx.Get(key).Int()        if err != nil && err != redis.Nil {            return err        }        if n == 0 {            return errors.New("票没了")        }        // actual opperation (local in optimistic lock)        n = n - 1        // runs only if the watched keys remain unchanged        _, err = tx.TxPipelined(func(pipe redis.Pipeliner) error {            // pipe handles the error case            pipe.Set(key, n, 0)            return nil        })        return err    }    return txf}func getTicket(client *redis.Client, key string) {    routineCount := 8    var wg sync.WaitGroup    wg.Add(routineCount)    for i := 0; i < routineCount; i++ {        go func(id int) {            defer wg.Done()            for {                err := client.Watch(runTx(key, id), key)                if err == nil {                    fmt.Println(id, "成功")                    return                } else if err.Error() == "票没了" {                    fmt.Println(id, "票没了")                    return                } else {                    fmt.Println(err, "retry")                }            }        }(i)    }    wg.Wait()}

Github code: https://github.com/defp/redis…

current ticket_count key val:  57 成功6 成功redis: transaction failed retryredis: transaction failed retryredis: transaction failed retryredis: transaction failed retryredis: transaction failed retryredis: transaction failed retryredis: transaction failed retry3 成功redis: transaction failed retryredis: transaction failed retryredis: transaction failed retryredis: transaction failed retry2 成功redis: transaction failed retryredis: transaction failed retryredis: transaction failed retryredis: transaction failed retry5 成功redis: transaction failed retryredis: transaction failed retryredis: transaction failed retry4 票没了1 票没了0 票没了

links


文章来源:智云一二三科技

文章标题:Redis optimistic lock with golang demo

文章地址:https://www.zhihuclub.com/5299.shtml

关于作者: 智云科技

热门文章

评论已关闭

1条评论

  1. Hi, i feel that i saw you visited my website so i got here to go back the favor?.I am trying to in finding things to improve my site!I guess its ok to use some of your concepts!!

网站地图