最近在开发电商平台的子系统——储值卡系统,系统核心业务涉及到金额消费以及库存控制,因此为了解决建立在内存上高并发情况下的事务控制,使用了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)

redis原子性读写操作之LUA脚本和watch机制的更多相关文章

  1. Redis源码学习:Lua脚本

    Redis源码学习:Lua脚本 1.Sublime Text配置 我是在Win7下,用Sublime Text + Cygwin开发的,配置方法请参考<Sublime Text 3下C/C++开 ...

  2. Redis篇:事务和lua脚本的使用

    现在多数秒杀,抽奖,抢红包等大并发高流量的功能一般都是基于 redis 实现,然而在选择 redis 的时候,我们也要了解 redis 如何保证服务正确运行的原理 前言 redis 如何实现高性能和高 ...

  3. redis中的事务、lua脚本和管道的使用场景

    参考文章 : https://blog.csdn.net/fangjian1204/article/details/50585080

  4. Redis结合Lua脚本实现高并发原子性操作

    从 2.6版本 起, Redis 开始支持 Lua 脚本 让开发者自己扩展 Redis … 案例-实现访问频率限制: 实现访问者 $ip 在一定的时间 $time 内只能访问 $limit 次. 非脚 ...

  5. 新姿势!Redis中调用Lua脚本以实现原子性操作

    背景:有一服务提供者Leader,有多个消息订阅者Workers.Leader是一个排队程序,维护了一个用户队列,当某个资源空闲下来并被分配至队列中的用户时,Leader会向订阅者推送消息(消息带有唯 ...

  6. Redis进阶应用:Redis+Lua脚本实现复合操作

    一.引言 Redis是高性能的key-value数据库,在很大程度克服了memcached这类key/value存储的不足,在部分场景下,是对关系数据库的良好补充.得益于超高性能和丰富的数据结构,Re ...

  7. .Net Core使用分布式缓存Redis:Lua脚本

    一.前言 运行环境window,redis版本3.2.1.此处暂不对Lua进行详细讲解,只从Redis的方面讲解. 二.Redis的Lua脚本 在Redis的2.6版本推出了脚本功能,允许开发者使用L ...

  8. 在redis一致性hash(shard)中使用lua脚本的坑

    redis 2.8之前的版本,为了实现支持巨量数据缓存或者持久化,一般需要通过redis sharding模式来实现redis集群,普遍大家使用的是twitter开源的Twemproxy. twemp ...

  9. Redis学习-LUA脚本

    最近在做K线的项目中,需要计算商品的分时数据.为了保证多台机器对同一商品的计算的有序性,所以在Redis中进行计算,同时为了保证在分时数据计算过程的原子性所以使用了LUA脚本,Redis内置了对LUA ...

随机推荐

  1. css pre标签

    浏览器:firfox49.0.2 在使用<pre>标签输出格式化文本的时候,遇到了一个小问题. 要在页面的底部输出两行文本,但是最后一行的文字总是距离屏幕的底部太大.下面图中的样子: 相关 ...

  2. CentOS7下安装和使用Xdebug

    wget http://xdebug.org/files/xdebug-2.4.0rc4.tgztar xvzf xdebug-2.4.0rc4.tgzcd xdebug-2.4.0RC4phpize ...

  3. PDO 用法学习

    PDO: php data object数据库访问抽象层 基于驱动:1.安装扩展 php_pdo.dll2.安装驱动 php_pdo_mysql.dll linux 编译时参数:--with-pdo= ...

  4. node04-buffer

    目录:node01-创建服务器 node02-util node03-events node04-buffer node05-fs node06-path node07-http node08-exp ...

  5. vue-cli构建vue项目

    参考资料:Vue2.0 新手完全填坑攻略—从环境搭建到发布 1.Node.js安装 https://nodejs.org/en/download/ 2.安装vue-cli npm install -g ...

  6. Gamma校正与线性空间

    基础知识部分 为了方便理解,首先会对(Luminance)的相关概念做一个简单介绍.如果已经了解就跳到后面吧. 我们用Radiant energy(辐射能量)来描述光照的能量,单位是焦耳(J),因为光 ...

  7. LeetCode——Best Time to Buy and Sell Stock II (股票买卖时机问题2)

    问题: Say you have an array for which the ith element is the price of a given stock on day i. Design a ...

  8. [leetcode] 题型整理之排列组合

    一般用dfs来做 最简单的一种: 17. Letter Combinations of a Phone Number Given a digit string, return all possible ...

  9. Java基础知识点2:hashCode()方法

    hashCode()方法基本实现 hashCode方法是Java的Object类所定义的几个基本方法之一.我们可以深入到Object类的源码中去查看: public native int hashCo ...

  10. 图形化查看maven的dependency依赖

    开发项目的时候,我们想知道一个maven的依赖库是来自那个工程,eclipse有插件可以直接看Dependency Hierarchy,推荐一个第三方的工具yED 在工程的pom.xml文件中添加如下 ...