1、引入依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>${redisson.version}</version>
</dependency>
<redisson.version>2.15.2</redisson.version>
2、编写接口类
package com.hmblogs.backend.controller;
import com.hmblogs.backend.dao.StockMapper;
import com.hmblogs.backend.entity.Stock;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
@RestController
@Slf4j
public class OrderRedissionController {
@Autowired
private StockMapper stockMapper;
@Autowired
private RedissonClient redissonClient;
//商品key名字
private String shangpingKey = "computer_key";
//获取锁的超时时间 秒
/**
* 该接口逻辑中已模拟并发,调用该接口不用做压测也行。
* @return
*/
@GetMapping("/redission/qiangdan")
public List<String> qiangdan() {
//抢到商品的用户
List<String> shopUsers = new ArrayList<>();
//构造很多用户
List<String> users = new ArrayList<>();
for(int i=0;i<16;i++) {
users.add("神牛-" + i);
}
//模拟开抢
users.parallelStream().forEach(user -> {
String shopUser = qiang(user);
if (!StringUtils.isEmpty(shopUser)) {
shopUsers.add(shopUser);
}
});
return shopUsers;
}
/**
* 模拟抢单动作
*
* @param user
* @return
*/
private String qiang(String user) {
RLock rLock = redissonClient.getLock(shangpingKey);
rLock.lock(60, TimeUnit.SECONDS);
//用户b拿到锁
log.info("用户{}拿到锁...", user);
try {
int id = 1111;
Stock stock = new Stock();
stock.setId(id);
Stock stockDo = stockMapper.findById(stock);
Integer quantity = stockDo.getQuantity();
if(quantity!=null && quantity>0){
stockMapper.updateStockById(stock);
log.info("update success.");
}else{
log.info("no update.");
}
} finally {
log.info("用户{}释放锁...", user);
//释放锁
rLock.unlock();
}
return user;
}
/**
* 调用该接口需要做压测
*/
@GetMapping("/redission/qiangdan22")
public void qiangdan22() {
RLock rLock = redissonClient.getLock(shangpingKey);
rLock.lock(60, TimeUnit.SECONDS);
//用户b拿到锁
log.info("用户拿到锁...");
try {
int id = 1111;
Stock stock = new Stock();
stock.setId(id);
Stock stockDo = stockMapper.findById(stock);
Integer quantity = stockDo.getQuantity();
if(quantity!=null && quantity>0){
stockMapper.updateStockById(stock);// 库存减1
log.info("update success.");
}else{
log.info("no update.");
}
} finally {
log.info("用户释放锁...");
//释放锁
rLock.unlock();
}
}
}
3、验证这2个接口,库存最后都是0,而不是负数。
3.1、验证第1个接口

3.2、验证第2个接口,要做压测。


1364

被折叠的 条评论
为什么被折叠?



