通过Expire实现Redis锁机制

在我们的业务系统中,可能因为某种原因,用户会不断的点击表单提交按钮,为了较少对系统的 无意义访问、暴力提交

以及用户体验,我们利用redis的过期时间简单的实现了一种Redis锁

当用户提交表单的时候,我们通过对表单数据以及用户唯一标识例如userNo进行加密,当做我们缓存的唯一key


import java.security.MessageDigest;

public static String genLockKey(String formData, String userNo){
		StringBuilder builder = new StringBuilder();
		MessageDigest md;
		try {
			md = MessageDigest.getInstance("MD5");
			StringBuffer lockKey = new StringBuffer(""); 
			lockKey.append(userNo);
			lockKey.append(formData);
			md.update( lockKey.toString().getBytes() );
			for ( byte b : md.digest() ){
				builder.append( Integer.toHexString( (b >> 4) & 0xf ) );
				builder.append( Integer.toHexString( b & 0xf ) );
			}
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return builder.toString();
	}

然后我们判断判断redis 中是否缓存了这个key,如果有缓存,则提醒用户不要重复提交,否则我们做redis缓存

String lockKey = CryptUtils.genLockKey(formData, user.getNo());
if (RedisLock.isLock(lockKey)) {
     // 不能重复提交
     logger.error("提交出错 - 不能重复提交报销单!");
     returnVo.setMsg("温馨提示 - 不能重复提交报销单!");
     return JsonUtils.toJson(returnVo);
 }
RedisLock.lock(lockKey, 2);
//.....剩余的业务逻辑

接下来上我们RedisLock 的实现


import java.util.concurrent.TimeUnit;

import org.springframework.data.redis.core.RedisTemplate;

import com.ys.tools.common.SpringContextHolder;

public class RedisLock {

	/**
	 * 加锁
	 * 
	 * @param key
	 * @param minutes
	 *            失效的分钟数
	 */
	public static void lock(String key, int seconds) {
		getRedisTemplate().opsForValue().set(key, key, seconds,
				TimeUnit.SECONDS);
	}

	/**
	 * 判断是否还在锁定状态
	 * 
	 * @param key
	 * @return true 锁定 false 已经解除锁定
	 */
	public static boolean isLock(String key) {
		Long flag = getRedisTemplate().getExpire(key);
		return flag > 0;
	}
	
	/**
	 * 解锁
	 * @param key
	 */
	public static void unLock(String key) {
		getRedisTemplate().delete(key);
	}

	private static RedisTemplate<String, String> getRedisTemplate() {
		return SpringContextHolder.getBean("redisTemplate");

	}

}

其实业务逻辑很简单,思想也很简单。

对表单数据进行缓存并设置过期时间,如果过期时间内点击按钮 缓存存在 ,则进行页面提示,如果不存在缓存则进行业务处理以及增加缓存防止重复点击 So Easy~~

你可能感兴趣的:(Redis)