Redis事务测试

1.Redis Java client

安装Redis: http://blog.csdn.net/caicongyang/article/details/50639052

关于Redis Java客户端的demo可以参考我的例子:http://blog.csdn.net/caicongyang/article/details/50642979

2.Redis事务(测试结论)

  1). 在Redis事务中的所有命令都将会被串行化的顺序执行(既单线程),事务执行期间,Redis不会再为其它客户端的请求提供任何服务,从而保证了事物中的所有命令被原子的执行。
  2). 和关系型数据库中的事务相比,在Redis事务中如果有某一条命令执行失败,其后的命令仍然会被继续执行。
  3).调用jedis.watch(…)方法来监控key,如果调用后key值发生变化,则整个事务会执行失败。

3.命令行测试

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"

2.2失败执行事务

#初始化值
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"

2.3回滚

#初始化
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> 

3.Jedis测试demo

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

记录与分享,你我共成长 -from  caicongyang



你可能感兴趣的:(transaction,Redis事务测试,Jedis+watch,+wacth,Jedis事务)