redis 事物限制频率和获得令牌

阅读更多
package com.dongnaoedu.tony.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisStringCommands.SetOption;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.stereotype.Component;

@Component
public class MiaoshaService {

private final Logger logger = LoggerFactory.getLogger(MiaoshaService.class);

@Autowired
StringRedisTemplate stringRedisTemplate;

@Autowired
DatabaseService databaseService;

/**
* 秒杀具体实现
*
* @param goodsCode
*            商品编码
* @param userId
*            用户ID
* @return
*/
public boolean miaosha(String goodsCode, final String userId) {
// 方案3: 频率限制
// 用户操作频率限制,5秒内允许访问一次
// set setnx setex
boolean value = stringRedisTemplate.execute(new RedisCallback() {

@Override
public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
Boolean result = connection.set(userId.getBytes(), "".getBytes(), Expiration.milliseconds(10000L),
SetOption.SET_IF_ABSENT);
return result;
}
});
if (!value) {
System.out.println("被限制操作频率啦,用户:" + userId);
return false;
}

// 方案4: 令牌机制
// 取令牌,拿到令牌的允许尝试购买
String token = stringRedisTemplate.opsForList().leftPop("token_list");
if (token == null || "".equals(token)) {
System.out.println("没抢到Token,不参与秒杀,用户:" + userId);
return false;
}

boolean result = databaseService.buy(goodsCode, userId);
System.out.println("秒杀结果:" + result);
return result;
}
}

你可能感兴趣的:(redis)