关于Redis Java客户端的demo可以参考我的例子:http://blog.csdn.net/caicongyang/article/details/50642979
MULTI/EXEC/DISCARD/WATCH
2.1成功执行事务
#初始化值 127.0.0.1:6379> set num 20 OK #开启事务 127.0.0.1:6379> multi OK #将num增加1,可以看到redis并没有立即执行,而是加入了队列中 127.0.0.1:6379> incr num QUEUED #将num减去1,同样可以看到redis并没有立即执行,而是加入了队列中 127.0.0.1:6379> decr num QUEUED #提交执行,看到两次执行的结果 127.0.0.1:6379> exec 1) (integer) 21 2) (integer) 20 #最终确认数值正确为20 127.0.0.1:6379> get num "20"
#初始化值 127.0.0.1:6379> set num 15 OK #开启事务 127.0.0.1:6379> multi OK #将caicongyang减去1,可以看到redis并没有立即执行,而是加入了队列中 127.0.0.1:6379> decr caicongyang QUEUED #此命令为list的命令,执行应该报错! 127.0.0.1:6379> lpop caicongyang QUEUED #将caicongyang增加1,可以看到redis并没有立即执行,而是加入了队列中 127.0.0.1:6379> incr caicongyang QUEUED #执行结果,看到lpop 命令出错,其他的都正常执行 127.0.0.1:6379> exec 1) (integer) 14 2) (error) WRONGTYPE Operation against a key holding the wrong kind of value 3) (integer) 15 #最终结果也符合预期 127.0.0.1:6379> get caicongyang "15"
#初始化 127.0.0.1:6379> set num 10 OK #开启事务 127.0.0.1:6379> multi OK #自增加 127.0.0.1:6379> incr num QUEUED #回滚 127.0.0.1:6379> discard OK #最终结果正确 127.0.0.1:6379> get num "10" 127.0.0.1:6379>
package com.caicongyang.redis; import java.util.List; import org.junit.Test; import redis.clients.jedis.Jedis; import redis.clients.jedis.Pipeline; import redis.clients.jedis.Transaction; public class JedisAdvanceFeaturesDemo { /** * 回滚测试 */ @Test public void testTransaction(){ Jedis jedis = new Jedis("192.168.150.137",6379); //---exec 执行事务队列内命令------------- Transaction t = jedis.multi();//开始事务 t.set("husband", "Tom"); t.set("wife", "Mary"); t.exec();//执行事务 //------discard 取消执行事务内命令--------- Transaction t2 = jedis.multi(); t2.set("test", "0"); t2 = jedis.multi(); t2.set("test", "1"); t2.discard(); String husband = jedis.get("husband"); String wife = jedis.get("wife"); String test = jedis.get("test"); System.out.println("husband:" + husband); System.out.println("wife:" + wife); System.out.println("test:" + test); //null 原因:开启事务后未提交,则无结果 jedis.close(); } /** * 测试watch * @throws Exception */ @Test public void testWatch() throws Exception{ Jedis jedis = new Jedis("192.168.150.137",6379); jedis.set("caicongyang", "goodboy"); jedis.watch("caicongyang"); Thread.sleep(3000L); new Thread(new Runnable() { @Override public void run() { Jedis j1 = new Jedis("192.168.150.137",6379); Transaction multi = j1.multi(); multi.set("caicongyang", "good"); multi.exec(); System.out.println(j1.get("caicongyang"));//结果是:boy j1.close(); } }).start(); //未执行下面的事务;原因:我们调用jedis.watch(…)方法来监控key,如果调用后key值发生变化,则整个事务不会执行。 Transaction multi = jedis.multi(); multi.set("caicongyang", "boy"); List<Object> list = multi.exec(); //事务结果:异常应该上面的提交没有执行 System.out.println(list.get(0).toString()); //NullPointerExecption String result = jedis.get("caicongyang"); System.out.println(result); //结果是:boy } /** * 持久化测试 */ @Test public void testPersis(){ Jedis jedis = new Jedis("192.168.150.137",6379); jedis.set("ccy", "handsome boy"); jedis.persist("ccy"); //重新启动机器依然存在 String value = jedis.get("ccy"); System.out.println(value); jedis.close(); } /** * 测试管道 */ @Test public void testPipelined(){ Jedis jedis = new Jedis("192.168.150.137",6379); Pipeline pipeline = jedis.pipelined(); long start = System.currentTimeMillis(); for (int i = 0; i < 100000; i++) { pipeline.set("p" + i, "p" + i); } //异步返回结果 List<Object> results = pipeline.syncAndReturnAll(); long end = System.currentTimeMillis(); System.out.println("Pipelined SET: " + ((end - start)/1000.0) + " seconds"); //10000次插入仅需不到1秒 System.out.println(results.size()); jedis.disconnect(); } }
更多多线程精彩内容请继续关注我的博客:http://blog.csdn.net/caicongyang