1. 程式人生 > >通過Expire實現Redis鎖機制

通過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~~