redis抢购实现关键代码

本文介绍了一种使用RedisTemplate执行Redis事务的方法,并通过管道(Pipelined)操作避免了资源未释放的问题。该方法适用于更新用户信息同时减少库存场景,确保了数据的一致性和事务的原子性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在使用redis的时候如果redisTemplate.execute方法执行多条redis命令,则会出现资源无法释放的问题,如果改成redisTemplate.executePipelined则不会出现;

/**
* 更新用户信息并将股票余数减1
*
* @param ppkey
* 队列key:set+mobile
* @param upkey
* 股票余数
* @param rushuser
* @return
*/
protected boolean updateUserAndDecrStock(final String ppkey, final String upkey, final RushUser rushuser) {
boolean flag = false;
try {
redisTemplate.executePipelined(new RedisCallback<Boolean>() {
@Override
public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
byte[] upkeyb = redisTemplate.getStringSerializer().serialize(upkey);
byte[] stockKey = redisTemplate.getStringSerializer().serialize(RedisCounterEnum.STOCK_COUNT.getCounterName());// 股权证编号(抢购成功时记录,从1开始递增)
byte[] ppkeyb = redisTemplate.getStringSerializer().serialize(ppkey);
connection.watch(upkeyb, stockKey);
connection.multi();
Object counter = redisTemplate.opsForValue().get(upkey);
Object stockNoObject = redisTemplate.opsForValue().get(RedisCounterEnum.STOCK_COUNT.getCounterName());
int count = Integer.valueOf(counter == null ? "0" : counter.toString());
int stock = Integer.valueOf(stockNoObject == null ? "0" : stockNoObject.toString());
if (count > 0) {
connection.decr(upkeyb);
String stockNo = (stock + 1) + "";
rushuser.setStockno(stockNo);// 设置股权证编号
String value = ZGUtil.objectToJson(rushuser);
connection.set(stockKey, redisTemplate.getStringSerializer().serialize(stockNo));
connection.set(ppkeyb, redisTemplate.getStringSerializer().serialize(value));
}
connection.exec();
return null;
}
});
flag = true;
} catch (Exception e) {
logger.error(e.getMessage(), e);
flag = false;
}
return flag;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值