一看就会的超详细教程:SpringBoot整合MybatisPlus!>>>
1.自己实现
private static String REDIS_LOCK = "redis_lock";
@Autowired
private RedissonClient redission;
/**
* 自定redisLock实现分布式锁,
* 使用 RedisTemplate + lua脚本实现
* @return
*/
@GetMapping("/mylock")
public String redisLock() {
String resoult = "";
long value = System.currentTimeMillis() + Thread.currentThread().getId();
try {
//1.原子性的设置锁,并且设置超时时间30s(加分布式锁)
Boolean flag = redisTemplate.opsForValue().setIfAbsent(REDIS_LOCK, value, 30l, TimeUnit.SECONDS);
if (!flag) {
return "抢占锁失败";
}
//2.获取库存数量
Object obj = redisTemplate.opsForValue().get("goods:100");
int goodsNum = obj == null ? 0 : Integer.parseInt(obj.toString());
if (goodsNum > 0) {
goodsNum = goodsNum - 1;
//3.把库存-1,并且设置会系统中
redisTemplate.opsForValue().set("goods:100", String.valueOf(goodsNum));
//模拟超时40秒
Thread.sleep(40000);
resoult = "成功购买到商品,剩余库存:" + goodsNum + " 件商品";
} else {
resoult = "商品已经售完/活动结束/调用结束,欢迎下次光临";
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//4.消除分布式锁(使用lua脚本实现删除锁)
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
//指定lua脚本
redisScript.setScriptText("if redis.call(\"get\",KEYS[1]) == ARGV[1] then\n" +
" return redis.call(\"del\",KEYS[1])\n" +
"else\n" +
" return 0\n" +
"end");
// 指定返回类型
redisScript.setResultType(Long.class);
// 参数一:redisScript,参数二:key列表,参数三:arg(可多个)
Long result = (Long) redisTemplate.execute(redisScript, Collections.singletonList(REDIS_LOCK), value);
if (result == 1) {
System.out.println("删除 锁 ok");
} else {
System.out.println("删除 锁 error");
}
}
System.out.println(resoult);
return resoult;
}
2.使用redisson实现
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.15.0</version>
</dependency>
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.setTransportMode(TransportMode.EPOLL);
config.useClusterServers()
.addNodeAddress("redis://192.168.2.13:6379");
return Redisson.create(config);
}
package com.un.project.system.controller.app;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
/**
* Redis Lock实现分布式锁
*
* @author shiye
* @create 2021-05-28 13:47
*/
@RestController
@RequestMapping("/ws/redis")
public class MyRedisLockController {
private static String REDIS_LOCK = "redis_lock";
@Autowired
private RedissonClient redission;
@GetMapping("/redissonlock")
public String redissonLock() {
String resoult = "";
long value = System.currentTimeMillis() + Thread.currentThread().getId();
//1.使用Redisson来加锁
RLock redissionLock = redission.getLock(REDIS_LOCK);
redissionLock.lock(30, TimeUnit.SECONDS);
try {
//2.获取库存数量
Object obj = redisTemplate.opsForValue().get("goods:100");
int goodsNum = obj == null ? 0 : Integer.parseInt(obj.toString());
if (goodsNum > 0) {
goodsNum = goodsNum - 1;
//3.把库存-1,并且设置会系统中
redisTemplate.opsForValue().set("goods:100", String.valueOf(goodsNum));
//模拟超时41秒
Thread.sleep(41000);
resoult = "成功购买到商品,剩余库存:" + goodsNum + " 件商品";
} else {
resoult = "商品已经售完/活动结束/调用结束,欢迎下次光临";
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//4.消除分布式锁(使用lua脚本实现删除锁)
if (redissionLock.isLocked() && redissionLock.isHeldByCurrentThread()) {
redissionLock.unlock();
}
}
System.out.println(resoult);
return resoult;
}
}