scala+redis实现分布式锁的示例代码
程序员文章站
2022-04-25 20:23:05
1、redis的底层是单例模式,意思是同一个脚本同一时刻只能有一个线程来执行,利用redis的这个特性来实现分布式锁。
首先实现工具类
package util...
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 }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。