Java开发Redis的事务与Watch原理分析

Redis中的业务(transaction)是一组指令的调集。业务同指令一样都是Redis最小的履行单位,一个业务中的指令要么都履行,要么都不履行。Redis业务的完结需求用到 MULTI 和 EXEC两个指令,业务开端的时分先向Redis服务器发送 MULTI 指令,然后顺次发送需求在本次业务中处理的指令,最终再发送 EXEC 指令表明业务指令完毕。严厉意义来讲,redis的业务和我们了解的传统数据库(如mysql)的业务是不一样的。

一丶redis中的业务界说

Redis中的业务(transaction)是一组指令的调集。

业务同指令一样都是Redis的最小履行单位,一个业务中的指令要么都履行,要么都不履行。

业务的原理是先将归于一个业务的指令发送给Redis,然后再让Redis顺次履行这些指令。

Redis确保一个业务中的一切指令要么都履行,要么都不履行。如果在发送EXEC指令前客户端断线了,则Redis会清空业务行列,业务中的一切指令都不会履行。而一旦客户端发送了EXEC指令,一切的指令就都会被履行,即便尔后客户端断线也没关系,因为Redis中现已记录了一切要履行的指令。

除此之外,Redis的业务还能确保一个业务内的指令顺次履行而不被其他指令刺进。试想客户端A需求履行几条指令,同时客户端B发送了一条指令,如果不运用业务,则客户端B的指令可能会刺进到客户端A的几条指令中履行。如果不期望发作这种情况,也能够运用业务。

二丶业务的应用

业务的应用非常遍及,如银行转账过程中A给B汇款,首要体系从A的账户中将钱划走,然后向B的账户添加相应的金额。这两个过程有必要归于同一个业务,要么全履行,要么全不履行。否则只履行第一步,钱就凭空消失了,这明显让人无法承受。

三丶和传统的业务不同

和传统的mysql业务不同的事,即便我们的加钱操作失利,我们也无法在这一组指令中让整个状况回滚到操作之前

四丶业务的过错处理

如果一个业务中的某个指令履行犯错,Redis会怎样处理呢?要回答这个问题,首要需求知道什么原因会导致指令履行犯错。

语法过错

语法过错指指令不存在或许指令参数的个数不对。比如:

redis>MULTIOKredis>SET key valueQUEUEDredis>SET key(error)ERR wrongnumber of arguments for ‘set‘ commandredis> errorCOMMAND key(error) ERR unknown command ‘errorCOMMAND‘redis> EXEC(error) EXECABORTTransaction discarded because of previous errors.

跟在MULTI指令后履行了3个指令:一个是正确的指令,成功地加入业务行列;其余两个指令都有语法过错。而只需有一个指令有语法过错,履行EXEC指令后Redis就会直接回来过错,连语法正确的指令也不会履行。

这儿需求留意一点:

Redis 2.6.5之前的版本会疏忽有语法过错的指令,然后履行业务中其他语法正确的指令。就此例而言,SET key value会被履行,EXEC指令会回来一个结果:1) OK。

运转过错

运转过错指在指令履行时呈现的过错,比如运用散列类型的指令操作调集类型的键,这种过错在实践履行之前Redis是无法发现的,所以在业务里这样的指令是会被Redis承受并履行的。如果业务里的一条指令呈现了运转过错,业务里其他的指令仍然会继续履行(包含犯错指令之后的指令),示例如下:

redis>MULTIOKredis>SET key 1QUEUEDredis>SADD key 2QUEUEDredis>SETkey 3QUEUEDredis>EXEC1) OK2) (error) ERR Operation against a keyholding the wrong kind of value3) OKredis>GET key"3"

可见尽管SADD key 2呈现了过错,可是SET key 3仍然履行了。

Redis的业务没有关系数据库业务供给的回滚(rollback)功用。为此开发者有必要在业务履行犯错后自己收拾剩余的摊子(将数据库恢复回业务履行前的状况等,这儿我们一般采取日志记录然后业务补偿的方式来处理,可是一般情况下,在redis做的操作不应该有这种强共同性要求的需求,我们以为这种需求为不合理的规划)。

五丶Watch指令

我们可能知道redis供给了根据incr指令来操作一个整数型数值的原子递加,那么我们假定如果redis没有这个incr指令,我们该怎样完结这个incr的操作呢?

那么我们下面的正主watch就要上场了。

怎么运用watch指令

正常情况下我们想要对一个整形数值做修正是这么做的(伪代码完结):

val = GET mykey val = val + 1 SET mykey $val

可是上述的代码会呈现一个问题,因为上面吧正常的一个incr(原子递加操作)分为了两部分,那么在多线程(分布式)环境中,这个操作就有可能不再具有原子性了。

研讨过java的juc包的人应该都知道cas,那么redis也供给了这样的一个机制,就是运用watch指令来完结的。

watch指令描绘

WATCH指令能够监控一个或多个键,一旦其中有一个键被修正(或删除),之后的业务就不会履行。监控一向继续到EXEC指令(业务中的指令是在EXEC之后才履行的,所以在MULTI指令后能够修正WATCH监控的键值)

运用watch完结incr

具体做法如下:

WATCH mykey val = GET mykey val = val + 1 MULTI SET mykey $val EXEC

和此前代码不同的是,新代码在获取mykey的值之前先通过WATCH指令监控了该键,尔后又将set指令包围在业务中,这样就能够有用的确保每个衔接在履行EXEC之前,如果当时衔接获取的mykey的值被其它衔接的客户端修正,那么当时衔接的EXEC指令将履行失利。这样调用者在判别回来值后就能够得悉val是否被从头设置成功。

留意点

因为WATCH指令的效果只是当被监控的键值被修正后阻止之后一个业务的履行,而不能确保其他客户端不修正这一键值,所以在一般的情况下我们需求在EXEC履行失利后从头履行整个函数。

履行EXEC指令后会撤销对一切键的监控,如果不想履行业务中的指令也能够运用UNWATCH指令来撤销监控。

完结一个hsetNX函数

我们完结的hsetNX这个功用是:仅当字段存在时才赋值。

为了防止竞态条件我们运用watch和业务来完结这一功用(伪代码):

WATCH key isFieldExists = HEXISTS key, field if isFieldExists is 1MULTI HSET key, field, value EXEC else UNWATCH return isFieldExists

在代码中会判别要赋值的字段是否存在,如果字段不存在的话就不履行业务中的指令,但需求运用UNWATCH指令来确保下一个业务的履行不会受到影响。

总结

以 上就是我对Java开发Redis的业务与Watch原理剖析问题及其优化总结,共享给我们,期望我们能够了解什么是Java开发Redis的业务与Watch原理剖析问题及其优化。觉得收成的话能够点个重视收藏转发一波喔,谢谢大佬们支撑!

1、多写多敲代码,好的代码与厚实的基础知识一定是实践出来的

2、能够去百度查找腾讯讲堂图灵学院的视频来学习一下java架构实战事例,还挺不错的。

最终,每一位读到这儿的网友,感谢你们本领心地看完。期望在成为一名更优异的Java程序员的道路上,我们能够一起学习、一起前进。

时间: 2024-08-29 07:36:29

Java开发Redis的事务与Watch原理分析的相关文章

Redis数据持久化机制AOF原理分析二

Redis数据持久化机制AOF原理分析二 分类: Redis 2014-01-12 15:36  737人阅读  评论(0)  收藏  举报 redis AOF rewrite 目录(?)[+] 本文所引用的源码全部来自Redis2.8.2版本. Redis AOF数据持久化机制的实现相关代码是redis.c, redis.h, aof.c, bio.c, rio.c, config.c 在阅读本文之前请先阅读Redis数据持久化机制AOF原理分析之配置详解文章,了解AOF相关参数的解析,文章链

【Redis源码剖析】 - Redis之事务的实现原理

原创作品,转载请标明:http://blog.csdn.net/Xiejingfa/article/details/51262268 今天为大家带来Redis中事务部分的源码分析.Redis的事务机制允许将多个命令当做一个独立的单元运行,主要包括multi.exec.watch.unwatch.discard五个相关命令.如果你还不熟悉这几个命令,可以先看看我的另一篇文章[Redis学习笔记(七)] Redis中的事务 本文所讲述的内容主要涉及redis.h和multi.c两个源文件,依据惯例,

突破Java面试-Redis集群模式的原理

1 面试题 Redis集群模式的工作原理说一下?在集群模式下,key是如何寻址的?寻址都有哪些算法?了解一致性hash吗? 2 考点分析 Redis不断在发展-Redis cluster集群模式,可以做到在多台机器上,部署多个实例,每个实例存储一部分的数据,同时每个实例可以带上Redis从实例,自动确保说,如果Redis主实例挂了,会自动切换到redis从实例顶上来. 现在新版本,大家都是用Redis cluster的,也就是原生支持的集群模式,那么面试官肯定会就redis cluster对你来

Java开发中使用事务

一.      XML,使用tx标签配置拦截器实现事务 二.      Annotation方式 一.XML,使用tx标签配置拦截器实现事务 中主要配置中是tx:advice和aop:config两个配置节,以Spring AOP的方式实现事务管理. tx:advice配置了事务的管理者是transactionManager,同时tx:method也规定了如果方法名匹配"add*"和"get*"方法时使用事务,propagation是设定事务的传播级别.除了&quo

JAVA基础学习之-AQS的实现原理分析

AbstractQueuedSynchronizer是JUC的核心框架,其设计非常精妙. 使用了Java的模板方法模式. 首先试图还原一下其使用场景:对于排他锁,在同一时刻,N个线程只有1个线程能获取到锁:其他没有获取到锁的线程被挂起放置在队列中,待获取锁的线程释放锁后,再唤醒队列中的线程. 线程的挂起是获取锁失败时调用Unsafe.park()方法:线程的唤醒是由其他线程释放锁时调用Unsafe.unpark()实现.由于获取锁,执行锁内代码逻辑,释放锁整个流程可能只需要耗费几毫秒,所以很难对

Java原子性操作之——Atomic包的原理分析

Atomic: Atomic包是java.util.concurrent下的另一个专门为线程安全设计的java的包,包含多个原子性操作的类.基本特性就是在多线程情况下,当多个线程想要同时操作这些类的某些实例方法时,具有排他性,也就是当某个线程在执行某个方法时,不会被其他线程打断,其他线程会在外部等待,一直等到该方法执行完毕,才由JVM从等待队列中选择另一个线程进入,这只是一种逻辑上的理解.实际上是借助硬件的相关指令来实现的,不会阻塞线程(只是在硬件级别去阻塞了).可以对基本数据,数组中的基本数据

支付宝app支付java后台流程及原理分析

java版支付宝app支付流程及原理分析 本实例是基于springmvc框架编写     一.流程步骤         1.执行流程           当手机端app(就是你公司开发的app)在支付页面时,调起服务端(后台第1个创建订单接口)接口,后台把需要调起支付宝支付的参数返回给手机端,手机端拿到         这些参数后,拉起支付宝支付环境完成支付,完成支付后会调异步通知(第2个接口),此时需要给支付宝返回成功或者失败信息,成功后会调用同步通知(第3个接口)         返回支付成

使用Java开发高性能网站需要关注的那些事儿

无论大型门户网站还是中小型垂直类型网站都会对稳定性.性能和可伸缩性有所追求.大型网站的技术经验分享值得我们去学习和借用,但落实到更具体的实践上并不是对所有网站可以适用,其他语言开发的网站我还不敢多说,但Java开发的系统,我还是能您给插上几句话: JVMJEE容器中运行的JVM参数配置参数的正确使用直接关系到整个系统的性能和处理能力,JVM的调优主要是对内存管理方面的调优,优化的方向分为以下4点:1.HeapSize             堆的大小,也可以说Java虚拟机使用内存的策略,这点是

架构之路—java开发必学知识点详细梳理

大家好,今天为大家带来了java开发必学的知识点的梳理,希望对小伙伴们在技术成长的道路上有所帮助. 数据库 mysql 1.sql基本语法(数据类型.增删改查.join.函数等). 2.索引(分类,失效条件,explain的使用,优化条件). 3.引擎的对比(InnoDB,MyISAM). 4.事物.隔离级别. 5.数据库的锁(行锁,表锁,读锁,写锁,悲观锁,乐观锁,以及加锁的select sql方式). 6.分库分表,主从复制,读写分离. 7.mysql的中间件 mycat nosql red