redis 读后写aba操作


	// redis  读后写aba操作,a操作
	@RequestMapping("/A")
	@ResponseBody
	public String optA(HttpServletResponse response) throws Exception {
		String res = null;

		List rs = null;
		redisUtil.getTemplate().setEnableTransactionSupport(true);
		try {
			do {
				redisUtil.getTemplate().watch("dayQuota");
				String dayQuota = redisUtil.getValue("dayQuota").toString();
				int dayQuotaint = Integer.parseInt(dayQuota);
				res = String.format("optA %d+1=%d", dayQuotaint, dayQuotaint + 1);
				dayQuotaint = dayQuotaint + 1;
				// 耗时操作
				Thread.sleep(5000);
				redisUtil.getTemplate().multi(); // 开始事务
				redisUtil.setValue("dayQuota", dayQuotaint);
				rs = redisUtil.getTemplate().exec();// 提交事务
				//System.out.println(JSON.toJSONString(rs, true));
				log.debug(res);

			} while (rs == null||rs.size()==0);// 多重检测,直到执行成功。
			
		} catch (Exception e) { // 如果key被改变,提交事务时这里会报异常
			e.printStackTrace();
		}
		redisUtil.getTemplate().setEnableTransactionSupport(false);
		
		return res;
	}

	// redis  读后写aba操作,b操作
	@RequestMapping("/B")
	@ResponseBody
	public String optB(HttpServletResponse response) throws Exception {
		String dayQuota = redisUtil.getValue("dayQuota").toString();
		int dayQuotaint = Integer.parseInt(dayQuota);
		String res = String.format("optB %d+1000=%d", dayQuotaint, dayQuotaint + 1000);
		dayQuotaint = dayQuotaint + 1000;
		log.debug(res);
		redisUtil.setValue("dayQuota", dayQuotaint);
		return res;
	}

首先请a接口,a接口会读取redis里的dayQuota值,并加1,然后挂起,这是请求b接口,修改dayQuota的值,a操作结束睡眠后,发现dayQuota被改变,会回滚,重新读取dayQuota值,并更新redis

1 a操作读取...
2 b操作读取并更新
3 optB 200000+1000=201000 
4 a操作更新失败
5 optA 200000+1=200001 
6 a操作再次更新
6 optA 201000+1=201001 

你可能感兴趣的:(Java)