jedis 鎖

用的是jedis 2.5.2.jar 


類:


import com.hoolai.fastaccess.common.log.Log;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

/**
 * Redis distributed lock implementation.
 * 
 * @author Alois Belaska <[email protected]>
 */
public class JedisLock {

	Jedis     jedis;
	
	JedisPool jedisPool;

	/**
	 * Lock key path.
	 */
	String lockKey;

	/**
	 * Lock expiration in seconds.
	 */
	int expireMsecs = 60 ;

	/**
	 * Acquire timeout in seconds.
	 */
	int timeoutMsecs = 0;

	boolean locked = false;


	/**
	 * Detailed constructor.
	 * 
	 * @param jedis
	 * @param lockKey
	 *            lock key (ex. account:1, ...)
	 * @param timeoutSecs
	 *            acquire timeout in seconds (default: 0 secs)
	 * @param expireMsecs
	 *            lock expiration in seconds (default: 60 secs)
	 */
	public JedisLock(JedisPool jedisPool, String lockKey, int timeoutMsecs, int expireMsecs) {
		this.jedisPool = jedisPool;
		this.jedis = jedisPool.getResource();
		this.lockKey = lockKey;
		this.timeoutMsecs = timeoutMsecs;
		this.expireMsecs = expireMsecs;
		if(timeoutMsecs > expireMsecs){
			throw new IllegalArgumentException("expireMsecs 必須大於 timeoutMsecs; expireMsecs:"+expireMsecs+",timeoutMsecs:"+timeoutMsecs);
		}
	}


	/**
	 * @return lock key
	 */
	public String getLockKey() {
		return lockKey;
	}



	/**
	 * Acquire lock.
	 * 
	 * @param jedis
	 * @return true if lock is acquired, false acquire timeouted
	 * @throws InterruptedException
	 *             in case of thread interruption
	 */
	public synchronized  boolean acquire() throws InterruptedException {
		try {
			if(jedis.exists(lockKey)&&jedis.ttl(lockKey)==-1){
				String expires = jedis.get(lockKey);
				if(expires!=null){
					//只有未過期 才設置過期時間
					if(Long.valueOf(expires) > System.currentTimeMillis()/1000){
						jedis.expireAt(lockKey,Long.valueOf(expires));
					}
				}
				
			}
			int timeout = timeoutMsecs*1000;
		
			int count= 0;
			while (true) {
				if(++count>2000){
					break;
				}
				
				Long expires = System.currentTimeMillis() / 1000 + expireMsecs + (expireMsecs>0 ? 0 : 1);
				String expiresStr = String.valueOf(expires);
				if (jedis.setnx(lockKey, expiresStr) == 1) {
					jedis.expireAt(lockKey, expires);
					locked = true;
					return true;
				}
				timeout -= 100;
				if (timeout < 0) {
					return false;
				}
				Thread.sleep(100);
			}
			return false;
		} catch (Exception e) {
			e.printStackTrace();
			Log.error("jedis acquire failed",e);
			return false;
		}
	}

	/**
	 * Acqurired lock release.
	 */
	public synchronized  void release() {
		if (locked) {
			jedis.del(lockKey);
			locked = false;
		}
		if(jedis!=null){
			jedisPool.returnResource(jedis);
		}
	}
}


用法:

package com.hoolai.fastaccess.web.domain.task;

import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Component;
import com.hoolai.fastaccess.common.jedislock.JedisLock;
import com.hoolai.fastaccess.common.jedislock.JedisLockFactory;
import com.hoolai.fastaccess.common.log.Log;
import com.hoolai.fastaccess.web.dao.mybatis.mapper.charge.ChargeOrderDao;
import com.hoolai.fastaccess.web.dao.mybatis.mapper.logs.StatisticsLogDao;
import com.hoolai.fastaccess.web.dao.mybatis.mapper.web.CollectChargeDao;
import com.hoolai.fastaccess.web.dao.mybatis.mapper.web.CollectOrderDao;
import com.hoolai.fastaccess.web.dao.mybatis.vo.CollectOrder;


@Component
public class CollectOrderTask {

	private final String KEYSTR = "collect_order_key";

	@Resource
	private JedisLockFactory jedisLockFactory;

	@Resource
	private StatisticsLogDao statisticsLogDao;

	@Resource
	private ChargeOrderDao chargeOrderDao;

	@Resource
	private CollectChargeDao collectChargeDao;

	@Resource
	private CollectOrderDao collectOrderDao;

	public void collect_order() {
		JedisLock jedisLock = null;
		try {
			jedisLock = jedisLockFactory.create(KEYSTR, 0, 20);
			boolean acquire = jedisLock.acquire();
			if (acquire) {
				collectOrderDao.delCollectOrder();
				List<CollectOrder> collectOrderList = chargeOrderDao
						.getCollectOrder();
				for (CollectOrder collectOrder : collectOrderList) {
					collectOrderDao.insert(collectOrder);
				}
			}
		} catch (InterruptedException e) {
			Log.error("create key_str:" + KEYSTR + " failed.", e);
			return;
		} catch (Exception e) {
			Log.error("create key_str:" + KEYSTR + " failed.", e);
		} finally {
			if (jedisLock != null) {
				try {
					jedisLock.release();
				} catch (Exception e) {
					Log.error("jedisLock.release() failed", e);
				}
			}
		}

	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章