Redis实现分布式锁

1、先说一下synchronized(集群下锁失效)

@RestController
public class IndexController {

	@Autowired
	private RedisTemplate<String, String> redisTemple;
	
	@RequestMapping("/deductStock")
	public String deductStock() {
		
		synchronized (this) {
		/*synchronized对单体项目还可以,对分布式集群部署项目不起作用。举例说明:我有2台服务器,通过nginx代理了,分别为tomcat1和tomcat2,设置redis库存为100,高并发场景
		当第一次分发到tomcat1中,第二次请求分发到tomcat中,如果tomcat1中程序还没执行完,还没减库存,tomcat2中已经获取了redis中的库存,值还是100,这样
		synchronized在集群中就无法起到锁的作用。如下图所示*/
			int stock = Integer.parseInt(redisTemple.opsForValue().get("stock"));
			if(stock > 0) {
				int realStock = stock - 1;
				redisTemple.opsForValue().set("stock",realStock+"");
				System.err.println("扣减成功,当前库存为"+realStock);
			}else {
				System.err.println("扣减失败,库存不足!");
			}
		}
		
		
		return "";
	}
}

2、Redis的SETNX实现锁机制(基本解决分布式锁,性能上还存在问题)

@RestController
public class IndexController {

	@Autowired
	private RedisTemplate<String, String> redisTemple;
	
	@RequestMapping("/deductStock")
	public String deductStock() {
		String lockKey="product_001";
		String clientId=UUID.randomUUID().toString();
		
		//Redis的SETNX实现锁机制(也就是只有不存在的时候才设置,可以利用它来实现锁的效果)
		try {
//			Boolean result = redisTemple.opsForValue().setIfAbsent(lockKey, "lzp");//就相当于jedis.setnx(k,v)
//			redisTemple.expire(lockKey, 10, TimeUnit.SECONDS);
			//以上2行也会存在问题,例如执行完第一行服务就挂了,锁就没有过期时间,一直不被释放;所以用下边的重载方法,具有原子性
			Boolean result = redisTemple.opsForValue().setIfAbsent(lockKey, clientId, 10, TimeUnit.SECONDS);
			if (!result) {
				return "很抱歉未抢到!";
			}

			//具体业务逻辑
			int stock = Integer.parseInt(redisTemple.opsForValue().get("stock"));
			if (stock > 0) {
				int realStock = stock - 1;
				redisTemple.opsForValue().set("stock", realStock + "");
				System.err.println("扣减成功,当前库存为" + realStock);
			} else {
				System.err.println("扣减失败,库存不足!");
			} 
		} finally {
			if(clientId.equals(redisTemple.opsForValue().get(lockKey))) {//确认是关闭的自己锁
				//释放锁
				redisTemple.delete(lockKey);
			}
		}
		return "";
	}
}

3、基于redission的分布式锁

引入pom.xml依赖

<dependency>
	<groupId>org.redisson</groupId>
	<artifactId>redisson</artifactId>
	<version>3.2.3</version>
</dependency>

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值