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

 更新时间:2019年06月19日 10:36:55   作者:张乐1993  
这篇文章主要介绍了scala+redis实现分布式锁的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

1、redis的底层是单例模式,意思是同一个脚本同一时刻只能有一个线程来执行,利用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
 }

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

相关文章

  • JavaWeb实现文件上传下载功能实例解析

    JavaWeb实现文件上传下载功能实例解析

    这篇文章主要为大家详细介绍了JavaWeb中的文件上传和下载功能的实现,在Web应用系统开发中,文件上传和下载功能是非常常用的功能,需要的朋友可以参考下
    2015-08-08
  • SpringBoot中使用Redis对接口进行限流的实现

    SpringBoot中使用Redis对接口进行限流的实现

    本文将结合实例代码,介绍SpringBoot中使用Redis对接口进行限流的实现,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • SpringBoot查看项目配置信息的几种常见方法

    SpringBoot查看项目配置信息的几种常见方法

    这篇文章主要为大家详细介绍了查看Spring Boot项目所有配置信息的几种方法,包括 Actuator端点,日志输出,代码级获取等方式并附带详细步骤和示例,希望对大家有一定的帮助
    2025-04-04
  • SpringCloud Eureka应用全面介绍

    SpringCloud Eureka应用全面介绍

    Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的
    2022-09-09
  • java导出Excel通用方法实例

    java导出Excel通用方法实例

    这篇文章主要介绍了java导出Excel方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • 如何在Spring Boot中使用OAuth2认证和授权

    如何在Spring Boot中使用OAuth2认证和授权

    这篇文章主要介绍了如何在Spring Boot中使用OAuth2认证和授权的相关资料,OAuth2.0是一种开放的授权协议,它允许用户授权第三方应用访问其账户(或资源),而无需共享其用户账户凭据,需要的朋友可以参考下
    2023-12-12
  • Spring Boot 实现程序的优雅退出(详细步骤)

    Spring Boot 实现程序的优雅退出(详细步骤)

    Spring Boot 为我们提供了优雅退出的功能,使应用程序能够在关闭时正常处理完所有当前请求,避免请求被中断导致数据丢失或不一致等问题,本文将全面介绍如何在 Spring Boot 应用程序中实现优雅退出,感兴趣的朋友跟随小编一起看看吧
    2024-03-03
  • SpringBoot实现文件上传功能

    SpringBoot实现文件上传功能

    这篇文章主要为大家详细介绍了SpringBoot实现文件上传功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • Maven如何打入依赖中指定的部分jar包

    Maven如何打入依赖中指定的部分jar包

    当项目运行的环境里已经有一个jar包是pom文件依赖其他项目的jar包,所以最后得到的项目jar包中还需要打入其他项目的最新代码,接下来通过本文给大家介绍Maven打入依赖jar包的操作工程,需要的朋友参考下吧
    2021-06-06
  • maven deploy时报错的解决方法

    maven deploy时报错的解决方法

    这篇文章主要介绍了maven deploy时报错的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09

最新评论