栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

scala+redis实现分布式锁的示例代码

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

scala+redis实现分布式锁的示例代码

1、redis的底层是单例模式,意思是同一个脚本同一时刻只能有一个线程来执行,利用redis的这个特性来实现分布式锁。

首先实现工具类

package utils
 
import CacheManager
 

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"
 
 
 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
   }
  )
 }
 
 
 
 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
 }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/137844.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号