Java Code Examples for redis.clients.jedis.Jedis#watch()

The following examples show how to use redis.clients.jedis.Jedis#watch() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: TransactionTest.java    From code with Apache License 2.0 6 votes vote down vote up
/**
 * 乐观锁:watch
 *
 */
public static int doubleAccount(Jedis jedis, String userId) {
    String key = keyFor(userId);
    while (true) {
        jedis.watch(key);
        int value = Integer.parseInt(jedis.get(key));
        value *= 2; // 加倍
        Transaction tx = jedis.multi();
        tx.set(key, String.valueOf(value));
        List<Object> res = tx.exec();
        if (res != null) {
            break; // 成功了
        }
    }
    return Integer.parseInt(jedis.get(key)); // 重新获取余额
}
 
Example 2
Source File: RedisDistributedLock.java    From Distributed-KV with Apache License 2.0 5 votes vote down vote up
@Override
public boolean unLock(String lockName, String lockSerialNum) {
	boolean result = false;
	String lock = "lock:" + lockName;
	
	Jedis conn = pool.getResource();
	// 循环尝试解锁
	// while循环适用于超时剥夺锁的情况
	while (true) {
		try {
			// 监视锁数据,一旦被人篡改则重试
			conn.watch(lock);
			// 当确认是自己上的锁时,利用实务进行解锁操作
			if (conn.get(lock).equals(lockSerialNum)) {
				Transaction transaction = conn.multi();
				transaction.del(lock);
				// 执行操作可能有隐患
				transaction.exec();
				result = true;
				System.out.println(Thread.currentThread().getName() + "redis锁解锁成功");
				System.out.println("+++++++++++++++++++");
			}
			conn.unwatch();
			break;
		} catch (JedisException e) {
			// conn.watch(lock)触发,重试解锁
			System.out.println(Thread.currentThread().getName() + "redis锁已被篡改,正在重试...");
			System.out.println("+++++++++++++++++++");
			// e.printStackTrace();
		} finally {
			// 关闭redis连接
			conn.close();
		}

	}

	return result;
}
 
Example 3
Source File: PasswordDB.java    From VileBot with MIT License 5 votes vote down vote up
/**
 * Add or modify a user's password
 * 
 * @param username unique user name
 * @param password the user's password (will be hashed)
 * @return true iff a new element was inserted
 */
public static boolean setUserPassword( String username, String password )
{
    Jedis jedis = pool.getResource();
    try
    {
        boolean newUser;

        Transaction trans;
        do
        {
            // Can't use intermediate results of a Redis transaction in that transaction, so watch the keys and do
            // the query before opening the transaction. The transaction will fail on exec() call if the keys
            // changed.
            jedis.watch( keyOfPassHash, keyOfPassSaltsHash );
            boolean exists = jedis.hexists( keyOfPassHash, username );

            trans = jedis.multi();
            // Create a salt as well as the new password entry if the user is new
            if ( !exists )
            {
                newUser = true;

                String salt = generateSalt();
                trans.hset( keyOfPassSaltsHash, username, salt );

                String hash = hash( password, salt );
                trans.hset( keyOfPassHash, username, hash );
            }
            else
                newUser = false;
        }
        while ( trans.exec() == null );

        return newUser;
    }
    finally
    {
        pool.returnResource( jedis );
    }
}
 
Example 4
Source File: SeckillServiceImpl.java    From jseckill with Apache License 2.0 4 votes vote down vote up
/**
 * @param seckillId
 * @param userPhone
 * @param md5
 * @return
 * @throws SeckillException
 * @TODO 先在redis里处理,然后发送到mq,最后减库存到数据库
 */
private SeckillExecution handleSeckillAsync(long seckillId, long userPhone, String md5)
        throws SeckillException {
    if (md5 == null || !md5.equals(getMD5(seckillId))) {
        logger.info("seckill_DATA_REWRITE!!!. seckillId={},userPhone={}", seckillId, userPhone);
        throw new SeckillException(SeckillStateEnum.DATA_REWRITE);
    }

    Jedis jedis = jedisPool.getResource();
    String inventoryKey = RedisKeyPrefix.SECKILL_INVENTORY + seckillId;
    if (jedis.sismember(RedisKey.SECKILLED_USER, String.valueOf(userPhone))) {
        //重复秒杀
        logger.info("seckill REPEATED. seckillId={},userPhone={}", seckillId, userPhone);
        throw new SeckillException(SeckillStateEnum.REPEAT_KILL);
    } else {
        String inventoryStr = jedis.get(inventoryKey);
        int inventory = Integer.valueOf(inventoryStr);
        if (inventory <= 0) {
            throw new SeckillException(SeckillStateEnum.SOLD_OUT);
        }
        jedis.watch(inventoryKey);
        Transaction tx = jedis.multi();
        tx.decr(inventoryKey);
        tx.sadd(RedisKey.SECKILLED_USER, String.valueOf(userPhone));
        List<Object> resultList = tx.exec();
        jedis.unwatch();
        if (resultList != null && resultList.size() == 2) {
            // 秒杀成功,后面异步更新到数据库中
            // 发送消息到消息队列
            SeckillMsgBody msgBody = new SeckillMsgBody();
            msgBody.setSeckillId(seckillId);
            msgBody.setUserPhone(userPhone);
            mqProducer.send(JSON.toJSONString(msgBody));

            // 立即返回给客户端,说明秒杀成功了
            SuccessKilled successKilled = new SuccessKilled();
            successKilled.setUserPhone(userPhone);
            successKilled.setSeckillId(seckillId);
            successKilled.setState(SeckillStateEnum.SUCCESS.getState());
            return new SeckillExecution(seckillId, SeckillStateEnum.SUCCESS, successKilled);
        } else {
            throw new SeckillException(SeckillStateEnum.RUSH_FAILED);
        }
    }
}
 
Example 5
Source File: DefaultRedis.java    From craft-atom with MIT License 4 votes vote down vote up
private String watch0(Jedis j, String... keys) {
	String r = j.watch(keys);
	bind(j);
	return r;
}