在Spring Boot中,可以使用Redis作为分布式锁来管理商品库存的加锁。以下是示例代码:
- 添加Redis依赖
在pom.xml中添加以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 配置Redis连接
在application.properties中配置Redis连接信息:
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=
spring.redis.database=0
- 编写加锁逻辑
@Service
public class ProductService {
@Autowired
private RedisTemplate<String, String> redisTemplate;
public boolean checkStock(String productId, int quantity) {
String key = "product." + productId + ".lock";
String value = UUID.randomUUID().toString();
try {
// 获取锁,锁的有效期为30秒
boolean locked = redisTemplate.opsForValue().setIfAbsent(key, value, 30, TimeUnit.SECONDS);
if (!locked) {
// 获取锁失败,说明其他线程正在处理,直接返回false
return false;
}
// 获取锁成功,校验库存
int stock = getStock(productId);
if (stock < quantity) {
// 库存不足,返回false
return false;
}
// 库存充足,扣减库存
reduceStock(productId, quantity);
return true;
} finally {
// 释放锁
if (value.equals(redisTemplate.opsForValue().get(key))) {
redisTemplate.delete(key);
}
}
}
public int getStock(String productId) {
// TODO: 查询库存
}
public void reduceStock(String productId, int quantity) {
// TODO: 扣减库存
}
}
在上面的代码中,checkStock方法用于校验库存和扣减库存。先获取锁,如果获取不到锁就直接返回false,否则执行校验和扣减库存的操作。最后释放锁。
- 测试加锁
@RunWith(SpringRunner.class)
@SpringBootTest
public class ProductServiceTest {
@Autowired
private ProductService productService;
@Test
public void testCheckStock() {
boolean result = productService.checkStock("1", 2);
Assert.assertTrue(result);
}
}
在测试中调用checkStock方法,并传入productId和quantity参数,如果返回true,则说明库存充足,扣减成功;如果返回false,则说明库存不足或者其他线程正在处理。