温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何在scala中使用redis实现分布式锁

发布时间:2021-04-09 16:13:16 来源:亿速云 阅读:385 作者:Leah 栏目:编程语言

本篇文章为大家展示了如何在scala中使用redis实现分布式锁,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

首先实现工具类

package utils
 
import CacheManager
 
/**
 * redis分布式锁
 */
object RedisTool {
 
 //加锁是否成功标志
 val LOCK_SUCCESS:String = "OK"
 
 //即当key不存在时,我们进行set操作;若key已经存在,则不做任何操作;
 val SET_IF_NOT_EXIST:String = "NX"
 
 //意思是我们要给这个key加一个过期的设置,具体时间由第五个参数决定。
 val SET_WITH_EXPIRE_TIME:String = "PX"
 
 val RELEASE_SUCCESS:String = "1"
 
 /**
  *
  * @param lockKey   锁
  * @param requestId  请求标识
  * @param expireTime  超期时间
  * @param isPersist  临时缓存或者永久缓存
  */
 def tryGetDistributedLock(lockKey:String, requestId:String, expireTime:Int,isPersist:Boolean=false){
  CacheManager.redisClientPool.withClient(
   client => {
    //val redisKeyPrefix = CacheManager.getRedisKeyPrefix(isPersist)
    client.select(CacheManager.redisDBNum)
    val result = client.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime)
    var flag = false
    if(LOCK_SUCCESS == result){
     flag = true
    }
    flag
   }
  )
 }
 
 
 /**
  *释放分布式锁
  * @param lockKey   锁
  * @param requestId  请求标识
  * @param expireTime  超期时间
  * @param isPersist  临时缓存或者永久缓存
  * @return
  */
 def releaseDistributedLock(lockKey:String, requestId:String,expireTime: Int = 10,isPersist:Boolean=false) ={
  CacheManager.redisClientPool.withClient(
   client => {
    val redisKeyPrefix = CacheManager.getRedisKeyPrefix(isPersist)
    client.select(CacheManager.redisDBNum)
    //lua脚本也是单例模式,同样也可以保证同一时刻只有一个线程执行脚本
    val lua =
     s"""
       |local current = redis.call('incrBy',KEYS[1],ARGV[1]);
       |if current == tonumber(ARGV[1]) then
       |  local t = redis.call('ttl',KEYS[1]);
       |  if t == -1 then
       |    redis.call('expire',KEYS[1],ARGV[2])
       |  end;
       |end;
       |return current;
      """.stripMargin
    val code = client.scriptLoad(lua).get
    val ret = client.evalSHA(code, List(redisKeyPrefix + lockKey),List(requestId,expireTime))
    val result = ret.get.asInstanceOf[Object].toString
    var flag = false
    if(result == RELEASE_SUCCESS){
     flag = true
    }
    flag
   }
  )
 }
 
}

2、实现CacheManager类

package utils
 
import com.redis.RedisClientPool
/**
 * 
 */
object CacheManager {
 
 val redisClientPool = "dev".equalsIgnoreCase(System.getenv("SCALA_ENV")) match {
  //开发环境
  case true => new RedisClientPool("127.0.0.1", 6379)
  //其他环境
  case false => new RedisClientPool("10.180.x.y", 6379, 8, 0, Some("root"))
 }
 
 val redisDBNum = 10
 
 def getRedisKeyPrefix(isPersist:Boolean) ={
  if(isPersist){
   //永久缓存前缀
   "persist_"
  }else{
   //临时缓存前缀
   "tmp_"
  }
 }
 
}

3、调用锁操作

def updateTableInfo(param:String) = {
  var resMap = Map[String,Any]()
  val lockKey = "mdms.MdmsUtils.updateTableInfo"
  //val requestId = UUID.randomUUID().toString().replace("-", "").toUpperCase()
  val flag = RedisTool.releaseDistributedLock(lockKey, "1")
  if(flag){
   try{
    
    //执行你的操作
    resMap = Map("code" -> 200 ,"msg" -> "成功")
   }catch {
    case e:Exception => {
     
     e.printStackTrace()
     resMap = Map("code" -> 200101 ,"msg" -> "执行失败")
    }
   }
   
  }else{
   resMap = Map("code" -> 200102 ,"msg" -> "操作冲突,已经被其他人捷足先登啦。")
  }
  resMap
 }

上述内容就是如何在scala中使用redis实现分布式锁,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI