redis 事务以及分布式锁

博客围绕Redis分布式事务展开讲解,虽未给出具体内容,但从标签可知重点在于Redis在分布式场景下的事务处理。

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

需要讲解的 都写在注释里面了

package com.fuchanghai.redis.lock;

import java.util.List;
import java.util.UUID;

import ch.qos.logback.core.net.server.Client;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import redis.clients.jedis.exceptions.JedisException;

public class RedisThread implements Runnable {
// 尝试着拿锁
	/*
	 * @key 在redis 中的key
	 * @timeout 超时时间, 怕占用太多资源
	 * @expire 失效时长。怕程序上锁的时候, 程序崩溃了,没法解锁
	 * */
	Jedis client=null;
	public String getLock(String key ,int timeout, int expire){
		try{
			client= RedisManager.getClient();
			// 这个值设置的是有一点讲究的, 因为setnx是锁住了, 但是其他线程是能够根据key 解锁的,所以我放入了
			// 一个uuid 当解锁的时候我们比对value 是否相等来判断是否是当前线程加的锁
			String value =UUID.randomUUID().toString();
			//如果等于一就说明 设置成功
			if(client.setnx(key, value)==1){
				client.expire(key+"Lock", expire);
				//这边返回json 是最好的 谁能保证a 里面没有,号呢, 到时候再分割就会出问题
				return value;
			}
			if(client.ttl(key)==-1){
				//如果进来了 说明没有设置失效时间。不设置的话,在当前代码之前某个线程setnx 成功了,但是程序崩溃了,岂不是一直要锁着
				client.expire(key, expire);
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally {
			if(client!=null){
				client.close();
			}
		}
		return null;
	}
	public boolean releaseLock(String key ,String value){
		Jedis client = RedisManager.getClient();

		try {

			System.out.println(value);

			while (true) {
				// 当watch 某个key 时,有多个线程对这个key操作, 将回滚
				client.watch(key);
				// 如果值相等,就说明是当前线程去删除这把锁
				if (value.equals(client.get(key))) {
					Transaction transation = client.multi();
					transation.del(key);
					List<Object> exec = transation.exec();
					
					if (exec == null) {
						//返回null 说明有多个线程对这个key 进行操作
						continue;
					}
					return true;
				}
				client.unwatch();
				break;
			}
		} catch (JedisException e) {
			e.printStackTrace();
		} finally {
			if (client != null) {
				client.close();
			}
		}

		return false;
	}
	public void run() {
		int count=0;
		// TODO Auto-generated method stub
		//如果失败再尝试两次
		while(count<3){			
			String value=getLock("fuchanghai" ,10000, 5000);
			if(value!=null){
				System.out.println("业务操作");
				releaseLock("fuchanghai", value);
				
			}else{
				count++;
			}
		}
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值