zoukankan      html  css  js  c++  java
  • redis原子性读写操作之LUA脚本和watch机制

      最近在开发电商平台的子系统——储值卡系统,系统核心业务涉及到金额消费以及库存控制,因此为了解决建立在内存上高并发情况下的事务控制,使用了spring封装的RedisTemplate执行lua脚本进行原子性操作,确保金额消费,库存按顺序处理,解决资源争抢。

      

      1.使用lua脚本

      Redis 使用单个 Lua 解释器去运行所有脚本,并且, Redis 也保证脚本会以原子性(atomic)的方式执行:当某个脚本正在运行的时候,不会有其他脚本或 Redis 命令被执行。这和使用 MULTI / EXEC 包围的事务很类似。在其他别的客户端看来,脚本的效果(effect)要么是不可见的(not visible),要么就是已完成的(already completed)。

      另一方面,这也意味着,执行一个运行缓慢的脚本并不是一个好主意。写一个跑得很快很顺溜的脚本并不难,因为脚本的运行开销(overhead)非常少,但是当你不得不使用一些跑得比较慢的脚本时,请小心,因为当这些蜗牛脚本在慢吞吞地运行的时候,其他客户端会因为服务器正忙而无法执行命令。

      2.实现watch机制

      

      WATCH key [key ...]

      监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

      

      MULTI

      标记一个事务块的开始。

      事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令原子性(atomic)地执行。

      EXEC

      执行所有事务块内的命令。

      假如某个(或某些) key 正处于 WATCH 命令的监视之下,且事务块中有和这个(或这些) key 相关的命令,那么 EXEC 命令只在这个(或这些) key 没有被其 他命令所改动的情况下执行并生效,否则该事务被打断(abort)。

        例子:

      

      # 事务被成功执行
    
      redis> MULTI
      OK
    
      redis> INCR user_id
      QUEUED
    
      redis> INCR user_id
      QUEUED
    
      redis> INCR user_id
      QUEUED
    
      redis> PING
      QUEUED
    
      redis> EXEC
      1) (integer) 1
      2) (integer) 2
      3) (integer) 3
      4) PONG
    
    
      # 监视 key ,且事务成功执行
    
      redis> WATCH lock lock_times
      OK
      redis> MULTI   OK   redis> SET lock "huangz"   QUEUED   redis> INCR lock_times   QUEUED   redis> EXEC   1) OK   2) (integer) 1   # 监视 key ,且事务被打断   redis> WATCH lock lock_times   OK   redis> MULTI   OK   redis> SET lock "joe" # 就在这时,另一个客户端修改了 lock_times 的值   QUEUED   redis> INCR lock_times   QUEUED   redis> EXEC # 因为 lock_times 被修改, joe 的事务执行失败   (nil)
  • 相关阅读:
    ThreadLocal 详解
    外键的约束(Mysql、PostgreSQL)
    Linux命令中,$、#、@、0、1、2、*、?的作用
    $.ajax 方法参数总是记不住,在这里记录一下
    SVN提示https证书验证失败问题svn: E230001: Server SSL certificate verification failed:
    各类资源地址整合
    CentOS 7 上安装vim 解決 centos -bash: vim: command not found
    Beyond Compare 4提示已经过了30天试用期,破解方式,亲测可用
    Django 04 模板标签(if、for、url、with、autoeacape、模板继承于引用、静态文件加载)
    Django 03 模板路径、模板变量、常用的过滤器
  • 原文地址:https://www.cnblogs.com/cl2Blogs/p/6097206.html
Copyright © 2011-2022 走看看