mysql中也存在事务的概念。其实事务的定义是一样的。一组操作的集合,作为一个整体,要么全执行,要么全不执行。

redis设置事务三步骤:

  1. 开始事务 :multi
  2. 操作加入事务队列
  3. 执行事务 :exec

事务意味着 两个意思

  • 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断,这个很重要。
  • 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

事务的好处就是可以保证 一组操有顺序执行,这个过程中不会插入其他操作。例如抽奖防止抽超过库存这一问题,当抽奖得到某一个奖品时,会先去取库存,看是不是大于0,如果大于0,我们再去把库存减一,然后返回。那么如何保证从取出库存到库存减一的这个过程中不插入其他操作呢。事务这个时候就能解决。(当然decr也能解决,而且更好)

用php模拟实现这个动作

$con->multi();
$a = $con->get('a');
$con->set('a',$a+1);
$con->get('a');
$res = $con->exec();
var_dump($res);

  

这个事务理论上能实现这个操作,但是实际上不会的。由于加入事务队列的操作不会立即执行,所以依赖于上一步的结果而进行的操作会有问题。
     a 的值是3,返回如下:
$res = array(3) {
[0]=>
string(1) "3"
[1]=>
bool(true)
[2]=>
string(1) "2"
}
事务中的$a 并没有获得返回,得到了一个object,下次计算当成数字1计算,所以最后永远返回2

所以我们看到,当事务中的操作存在依赖关系时,完全使用事务并不合适。当然,在不存在依赖关系的用这个事务步骤十分可行。如关注和被关注两个操作。
关注发生时,follow(a,b),follow(b,a)这两个 放到一个事务中。

那么如果事务中出现依赖关系怎么办呢?就是上一个问题怎么解决呢?这个请出事务系列的另一个方法watch
watch 的作用是监控一个或者多个键,监控之后,到事务开始这段时间内,若有一个及以上的键值发生了改变或删除(改变可能发生了多次,可能是不同的客户端进行的修改),事务不会执行。

加入事务队列的操作无法立即获取返回结果,所以依赖上一步结果进行下一步操作这样的事务是无法进行的,因为上一步的结果无法在实务中立即获取。

解决方法是 在事务开始前获取结果,然后监控这个key,再开始事务。

如果要想实现整个操作,还是要重新执行整个过程。
对于高并发,这么做并不合适,在watch值之后到multi开始这段时间内,很容易发生变化,导致不执行。

$con->watch('a');
$a = $con->get('a');
$con->multi();
$con->set('a',$a+1);
$con->get('a');
$res = $con->exec();
var_dump($res)

这个能返回想要的结果,最开始服务器中a =>1
array(2) {
[0]=>
bool(true)
[1]=>
string(1) "2"
}

获得了 +1 之后的结果。
$a = $con->get('a');
$con->multi();
这两步之间,若其他的客户端对a进行了改动,那么后面的事务不会执行的。如果想我们的事务执行,上面的那段代码必须重复执行,直到exec动作执行

<?php
class RedisTest{
private $redis_host = '192.168.211.129';
private $redis_port = '6379';
private $redis_timeout = '5';
private $redis_auth = 'foobared'; private $con; public function __construct(){
$this->con = new Redis();
$this->con->connect($this->redis_host,$this->redis_port,$this->redis_port);
$this->con->auth($this->redis_auth);
} /*
* 模拟实现初始化某个值的动作。不存在是赋值,存在则不做改变
*/
public function setXX($key,$val){
$this->con->watch($key);
$res = $this->con->get($key);
if($res === false){
$this->con->multi();
$this->con->set($key,$val);
$this->con->get($key);
$restult = $this->con->exec();
}else{
$restult = $res;
$this->con->unwatch();//watch监控的key只有在exec执行完才释放,所以unwatch取消监控
}
return $restult;
} //模拟实现redis的incr操作
public function incr($key){
$this->con->watch($key);
$val = $this->con->get($key);
$this->con->multi();
$this->con->set($key,$val+1);
$this->con->get($key);
$res = $this->con->exec();
if(empty($res)){
$this->incr($key);//如果exec没有执行,则这个动作不停执行,知道执行为止。在并发高的系统中,这个并不合适
}
return $res;
}
public function __destruct(){
$this->con->close();
} } class Client{
public function main(){
$obj = new RedisTest();
$res = $obj->setXX('a', 10);
$res = $obj->incr('a');
var_dump($res);
} } $obj = new Client();
$obj->main();

  

redis事务详解的更多相关文章

  1. 【Redis】Redis事务详解,Redis事务支持回滚(不支持悲观锁)

    1.redis事物参考:https://baijiahao.baidu.com/s?id=1613631210471699441&wfr=spider&for=pc (php操作red ...

  2. 5种Redis数据结构详解

    本文主要和大家分享 5种Redis数据结构详解,希望文中的案例和代码,能帮助到大家. 转载链接:https://www.php.cn/php-weizijiaocheng-388126.html 2. ...

  3. redis配置详解

    ##redis配置详解 # Redis configuration file example. # # Note that in order to read the configuration fil ...

  4. PHP mysql与mysqli事务详解

    官方对PHP连接到MySQL数据库服务器的三种主要的API简介如下: http://php.net/manual/zh/mysqli.overview.php PHP mysql与mysqli事务详解 ...

  5. CentOS7/RHEL7安装Redis步骤详解

    CentOS7/RHEL7安装Redis步骤详解 CentOS7/RHEL7安装Redis还是头一次测试安装了,因为centos7升级之后与centos6有比较大的区别了,下面我们就一起来看看Cent ...

  6. Redis协议详解

    smark Beetle可靠.高性能的.Net Socket Tcp通讯组件 支持flash amf3,protobuf,Silverlight,windows phone Redis协议详解 由于前 ...

  7. Java的JDBC事务详解

    Java的JDBC事务详解         分类:             Hibernate              2010-06-02 10:04     12298人阅读     评论(9) ...

  8. Redis学习——详解Redis配置文件(三)

    一.Redis脚本简介 在我们介绍Redis的配置文件之前,我们先来说一下Redis安装完成后生成的几个可执行文件: redis-server .redis-cli .redis-benchmark ...

  9. spring事务详解(五)总结提高

    系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.概念 ...

随机推荐

  1. Piwik 扩展获取客户端IP地址

    piwik 数据库浏览记录存放在piwik_log_visit表中 piwik_log_visit 表有个location_ip字段,该字段存储为Byte[]字节 解析出来后的IP地址为 XXX.XX ...

  2. Jasmine入门(结合示例讲解)

    参考: http://www.cnblogs.com/wushangjue/p/4541209.html http://keenwon.com/1191.html http://jasmine.git ...

  3. haslayout详解

    定义 haslayout是IE7-浏览器的特有属性.hasLayout是一种只读属性,有两种状态:true或false.当其为true时,代表该元素有自己的布局,否则代表该元素的布局继承于父元素. [ ...

  4. knockoutjs中使用mapping插件绑定数据列表

    使用KO绑定数据列表示例:   1.先申请V,T,T2三个辅助方法,方便调试.声明viewModel和加载数据时的映射条件mapping    2.先使用ko.mapping.fromJS()将原来的 ...

  5. 如何用Python寻找重复文件并删除

    在实际生活中,经常会有文件重复的困扰,即同一个文件可能既在A目录中,又在B目录中,更可恶的是,即便是同一个文件,文件名可能还不一样.在文件较少的情况下,该类情况还比较容易处理,最不济就是one by ...

  6. Android基于mAppWidget实现手绘地图(八)–获取用户地理位置

    你有两种方式确定用户的当前位置: 1.使用安卓标准方式 2. 使用MapWidget的监听器 标准方式: 在你的acivity中加入: LocationManager locManager = (Lo ...

  7. Web 开发精华文章集锦(jQuery、HTML5、CSS3)【系列二十七】

    <Web 前端开发精华文章推荐>2014年第6期(总第27期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...

  8. J2EE修炼之四书五经[转自2004年程序员]

    J2EE修炼之四书五经 作者:彭晨阳 J2EE其实没有四书五经,因为J2EE一直如汹涌澎湃的大江,推陈出新,不断高速发展,这是一种带领我们走向未来的技术.当然,如何在这种气势如虹的潮流之中不至于迷失方 ...

  9. 设计宝库:22套精美的 PhotoShop 素材免费下载

    <设计宝库>系列给大家带来22套精美的 PSD 设计素材,你可以免费下载使用.设计师经常会去网上搜罗各种各样的素材,这些免费素材不仅能帮助他们节省大量的时间,而且能有很好的效果.非常感谢那 ...

  10. HTML5 Web 客户端五种离线存储方式汇总

    最近折腾HTML5游戏需要离线存储功能,便把目前可用的几种HTML5存储方式研究了下,基于HT for Web写了个综合的实例,分别利用了Cookie.WebStorage.IndexedDB以及Fi ...