Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
PubTools-tools
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
liuxingyu
PubTools-tools
Commits
8f09d46a
Commit
8f09d46a
authored
Aug 09, 2023
by
liuxingyu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
首次提交
parent
a5f948d8
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
477 additions
and
0 deletions
+477
-0
RedissonLock.java
...in/java/com/mushiny/redisson/annotation/RedissonLock.java
+38
-0
RedissonLockAspect.java
.../java/com/mushiny/redisson/aspect/RedissonLockAspect.java
+98
-0
RedissonManager.java
...ain/java/com/mushiny/redisson/config/RedissonManager.java
+41
-0
PingApiForTestContraller.java
...mushiny/redisson/controller/PingApiForTestContraller.java
+44
-0
LockType.java
src/main/java/com/mushiny/redisson/enums/LockType.java
+45
-0
RedissonErrorCode.java
...ava/com/mushiny/redisson/execption/RedissonErrorCode.java
+25
-0
RedissonException.java
...ava/com/mushiny/redisson/execption/RedissonException.java
+30
-0
RedissonLockUtil.java
...ain/java/com/mushiny/redisson/utils/RedissonLockUtil.java
+142
-0
MwmsRedissonApplicationTests.java
...va/com/mushiny/redisson/MwmsRedissonApplicationTests.java
+14
-0
No files found.
src/main/java/com/mushiny/redisson/annotation/RedissonLock.java
0 → 100644
View file @
8f09d46a
/*
* Copyright (c) 2020 牧星仓库管理系统 All rights reserved.
*
* http://www.mushiny.com
*
* 版权所有,侵权必究!
*/
package
com
.
mushiny
.
redisson
.
annotation
;
import
com.mushiny.redisson.enums.LockType
;
import
java.lang.annotation.*
;
import
java.util.concurrent.TimeUnit
;
/**
* 操作分布式锁
*
* @author
*/
@Target
(
ElementType
.
METHOD
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Documented
public
@interface
RedissonLock
{
/** 锁类型*/
LockType
lockType
()
default
LockType
.
FAIR_LOCK
;
/** 获取锁等待时间,默认12秒*/
long
waitTime
()
default
12000L
;
/** 锁自动释放时间,默认10秒*/
long
leaseTime
()
default
10000L
;
/** 时间单位(获取锁等待时间和持锁时间都用此单位)*/
TimeUnit
unit
()
default
TimeUnit
.
MILLISECONDS
;
}
\ No newline at end of file
src/main/java/com/mushiny/redisson/aspect/RedissonLockAspect.java
0 → 100644
View file @
8f09d46a
package
com
.
mushiny
.
redisson
.
aspect
;
import
com.mushiny.redisson.annotation.RedissonLock
;
import
com.mushiny.redisson.execption.RedissonErrorCode
;
import
com.mushiny.redisson.execption.RedissonException
;
import
lombok.extern.slf4j.Slf4j
;
import
org.aspectj.lang.ProceedingJoinPoint
;
import
org.aspectj.lang.Signature
;
import
org.aspectj.lang.annotation.Around
;
import
org.aspectj.lang.annotation.Aspect
;
import
org.aspectj.lang.annotation.Pointcut
;
import
org.aspectj.lang.reflect.MethodSignature
;
import
org.redisson.api.RLock
;
import
org.redisson.api.RedissonClient
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
java.lang.reflect.Method
;
/**
* 数据过滤,切面处理类
*
* @author lxy
* @since 0.0.1
*/
@Aspect
@Component
@Slf4j
public
class
RedissonLockAspect
{
final
String
LOCKED
=
"REDISSON-LOCK"
;
@Autowired
RedissonClient
redissonClient
;
@Pointcut
(
"@annotation(com.mushiny.redisson.annotation.RedissonLock)"
)
public
void
pointCut
()
{
}
/**
* 公平锁切面
*/
@Around
(
"pointCut()"
)
public
Object
around
(
ProceedingJoinPoint
point
)
throws
Throwable
{
System
.
out
.
println
(
"开始加锁"
);
Signature
sig
=
point
.
getSignature
();
MethodSignature
methodSig
=
(
MethodSignature
)
sig
;
Object
target
=
point
.
getTarget
();
// 获取当前注解方法
Method
currentMethod
=
target
.
getClass
().
getMethod
(
methodSig
.
getName
(),
methodSig
.
getParameterTypes
());
RedissonLock
lockAction
=
currentMethod
.
getAnnotation
(
RedissonLock
.
class
);
// 方法名+入参进行加锁
StringBuilder
args
=
new
StringBuilder
();
//加锁key以REDISSONLOCK开头
String
key
=
LOCKED
+
currentMethod
.
getName
()
+
"_"
+
args
;
//这里根据wms场景需要,放的是公平锁,也可自行修改为重入锁和红锁
RLock
lock
=
getLock
(
key
,
lockAction
);
// 具有Watch Dog 自动延期机制 默认续30s
boolean
locked
=
lock
.
tryLock
(
lockAction
.
waitTime
(),-
1
,
lockAction
.
unit
());
//加锁失败给前端返回码
if
(!
locked
)
{
log
.
error
(
"加锁:{}失败,请重新尝试"
,
currentMethod
.
getName
());
throw
new
RedissonException
(
RedissonErrorCode
.
METHOD_IN_EXECUTION
);
}
try
{
// 加锁成功执行业务方法
return
point
.
proceed
();
}
catch
(
Exception
e
)
{
log
.
error
(
"执行方法:{}失败,请重新尝试"
,
currentMethod
.
getName
());
}
finally
{
//执行完成需要释放掉锁
lock
.
unlock
();
}
return
null
;
}
private
RLock
getLock
(
String
key
,
RedissonLock
lockAction
)
{
switch
(
lockAction
.
lockType
())
{
case
REENTRANT_LOCK:
return
redissonClient
.
getLock
(
key
);
case
FAIR_LOCK:
return
redissonClient
.
getFairLock
(
key
);
case
READ_LOCK:
return
redissonClient
.
getReadWriteLock
(
key
).
readLock
();
case
WRITE_LOCK:
return
redissonClient
.
getReadWriteLock
(
key
).
writeLock
();
default
:
throw
new
RuntimeException
(
"do not support lock type:"
+
lockAction
.
lockType
().
name
());
}
}
}
src/main/java/com/mushiny/redisson/config/RedissonManager.java
0 → 100644
View file @
8f09d46a
package
com
.
mushiny
.
redisson
.
config
;
import
org.redisson.Redisson
;
import
org.redisson.api.RedissonClient
;
import
org.redisson.config.Config
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
/**
* 描述信息
*
* @auther lxy
* @since 2023/8/4 13:39
*/
@Configuration
public
class
RedissonManager
{
@Value
(
"${spring.redis.host}"
)
private
String
addresses
;
@Value
(
"${spring.redis.password}"
)
private
String
password
;
@Value
(
"${spring.redis.port}"
)
private
String
port
;
@Bean
(
destroyMethod
=
"shutdown"
)
public
RedissonClient
redissonClient
()
{
Config
config
=
new
Config
();
//调用 useSingleServer 方法,选择单机模式,并指定 Redis 服务器的地址
config
.
useSingleServer
().
setAddress
(
"redis://"
+
addresses
+
":"
+
port
).
setPassword
(
password
);
System
.
out
.
println
(
"redis://"
+
addresses
+
":"
+
port
);
//调用 setConnectionMinimumIdleSize 方法,设置连接池最小空闲连接数为 10。
config
.
useSingleServer
().
setConnectionMinimumIdleSize
(
10
);
//调用 Redisson.create 方法,创建一个 RedissonClient 对象
RedissonClient
redissonClient
=
Redisson
.
create
(
config
);
return
redissonClient
;
}
}
src/main/java/com/mushiny/redisson/controller/PingApiForTestContraller.java
0 → 100644
View file @
8f09d46a
package
com
.
mushiny
.
redisson
.
controller
;
import
com.mushiny.redisson.enums.LockType
;
import
com.mushiny.redisson.utils.RedissonLockUtil
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
@RestController
@Slf4j
public
class
PingApiForTestContraller
{
@Autowired
RedissonLockUtil
redissonLockUtil
;
@PostMapping
(
"api/ping"
)
public
int
pingApi
(
@RequestParam
String
storageBinCode
,
@RequestParam
Long
workStationId
,
@RequestParam
Long
warehouseId
)
{
String
threadId
=
Thread
.
currentThread
().
getName
()
+
Thread
.
currentThread
().
getId
();
redissonLockUtil
.
getLockByKey
(
storageBinCode
+
workStationId
+
warehouseId
,
LockType
.
READ_LOCK
.
value
());
Boolean
getLock
=
redissonLockUtil
.
tryLock
(
null
,
storageBinCode
+
workStationId
+
warehouseId
,
LockType
.
REENTRANT_LOCK
.
value
());
if
(
getLock
)
{
System
.
out
.
println
(
threadId
+
"拿锁成功"
);
try
{
SimpleDateFormat
dateFormat
=
new
SimpleDateFormat
(
"yyyy-MM-dd HH:mm:ss"
);
Date
startDate
=
new
Date
();
System
.
out
.
println
(
threadId
+
"执行调度ping"
+
dateFormat
.
format
(
startDate
));
Thread
.
sleep
(
10000
);
System
.
out
.
println
(
"结束时间为"
+
dateFormat
.
format
(
new
Date
()));
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
else
{
System
.
out
.
println
(
"拿锁失败"
);
return
1
;
}
return
1
;
}
}
src/main/java/com/mushiny/redisson/enums/LockType.java
0 → 100644
View file @
8f09d46a
/**
* Copyright (c) 2019 人人开源 All rights reserved.
* <p>
* https://www.renren.io
* <p>
* 版权所有,侵权必究!
*/
package
com
.
mushiny
.
redisson
.
enums
;
/**
* 行政区域 级别枚举
*
* @author Elen elen.shen@mushiny.comn
* @since 2.1.0
*/
public
enum
LockType
{
/**
* 重入锁
*/
REENTRANT_LOCK
(
1
),
/**
* 公平锁
*/
FAIR_LOCK
(
2
),
/**
* 红锁
*/
READ_LOCK
(
3
),
/**
* 读写锁
*/
WRITE_LOCK
(
4
);
private
final
int
value
;
LockType
(
Integer
value
)
{
this
.
value
=
value
;
}
public
Integer
value
()
{
return
this
.
value
;
}
}
src/main/java/com/mushiny/redisson/execption/RedissonErrorCode.java
0 → 100644
View file @
8f09d46a
/*
* Copyright (c) 2020 牧星仓库管理系统 All rights reserved.
*
* http://www.mushiny.com
*
* 版权所有,侵权必究!
*/
package
com
.
mushiny
.
redisson
.
execption
;
/**
* 错误编码,由5位数字组成,前2位为模块编码,后3位为业务编码
* <p>
* 如:10001(10代表系统模块,001代表业务代码)
* </p>
*
* @author Elen elen.shen@mushiny.comn
* @since 2.1.0
*/
public
interface
RedissonErrorCode
{
int
INTERNAL_SERVER_ERROR
=
500
;
int
METHOD_IN_EXECUTION
=
10029
;
}
src/main/java/com/mushiny/redisson/execption/RedissonException.java
0 → 100644
View file @
8f09d46a
/*
* Copyright (c) 2020 牧星仓库管理系统 All rights reserved.
*
* http://www.mushiny.com
*
* 版权所有,侵权必究!
*/
package
com
.
mushiny
.
redisson
.
execption
;
/**
* 自定义异常
*
* @author Elen elen.shen@mushiny.comn
* @since 2.1.0
*/
public
class
RedissonException
extends
RuntimeException
{
private
static
final
long
serialVersionUID
=
1L
;
private
int
code
;
private
String
msg
;
public
RedissonException
(
int
code
)
{
this
.
code
=
code
;
this
.
msg
=
"pls wait to try"
;
}
}
\ No newline at end of file
src/main/java/com/mushiny/redisson/utils/RedissonLockUtil.java
0 → 100644
View file @
8f09d46a
package
com
.
mushiny
.
redisson
.
utils
;
import
com.mushiny.redisson.execption.RedissonErrorCode
;
import
com.mushiny.redisson.execption.RedissonException
;
import
lombok.extern.slf4j.Slf4j
;
import
org.redisson.api.RLock
;
import
org.redisson.api.RedissonClient
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
org.springframework.util.ObjectUtils
;
import
java.util.concurrent.TimeUnit
;
/**
* 描述信息
*
* @auther lxy0
* @since 2023/8/7 13:27
*/
@Slf4j
@Component
public
class
RedissonLockUtil
{
public
static
final
Long
WAITTIME
=
12000L
;
public
static
final
Long
RELEASETIME
=
14000L
;
@Autowired
RedissonClient
redissonClient
;
/**
* @param key
* @param lockType REENTRANT_LOCK:可重入锁 FAIR_LOCK:公平锁 READ_LOCK:红锁 WRITE_LOCK:读写锁
* @return
*/
public
RLock
getLockByKey
(
String
key
,
int
lockType
)
{
if
(
ObjectUtils
.
isEmpty
(
key
))
{
key
=
Thread
.
currentThread
().
getName
()
+
":"
+
Thread
.
currentThread
().
getId
();
}
if
(
ObjectUtils
.
isEmpty
(
lockType
))
{
lockType
=
1
;
}
switch
(
lockType
)
{
case
1
:
return
redissonClient
.
getLock
(
key
);
case
2
:
return
redissonClient
.
getFairLock
(
key
);
case
3
:
return
redissonClient
.
getReadWriteLock
(
key
).
readLock
();
case
4
:
return
redissonClient
.
getReadWriteLock
(
key
).
writeLock
();
default
:
throw
new
RuntimeException
(
"do not support lock type:"
+
lockType
);
}
}
/**
* 非阻塞式,在1s内尝试获取锁
* 获取成功默认锁30s,过期看门狗自动续期
*
* @param key
* @param waitTime
* @param type
* @return
*/
public
Boolean
tryLock
(
Long
waitTime
,
String
key
,
int
type
)
{
boolean
lock
=
false
;
if
(
ObjectUtils
.
isEmpty
(
waitTime
))
{
waitTime
=
WAITTIME
;
}
try
{
RLock
rLock
=
getLockByKey
(
key
,
type
);
lock
=
rLock
.
tryLock
(
waitTime
,
TimeUnit
.
MILLISECONDS
);
if
(!
lock
)
{
log
.
error
(
"分布式锁加锁:{}失败,请重新尝试"
);
throw
new
RedissonException
(
RedissonErrorCode
.
METHOD_IN_EXECUTION
);
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
lock
;
}
/**
* 当releaseTime传的是-1或者是空时,开启watch dog模式,会开启自动续锁
* 非阻塞式
* @param waitTime 等待时间
* @param releaseTime 锁有效时间
* @param key
* @param type
* @return
*/
public
Boolean
tryLock
(
Long
waitTime
,
Long
releaseTime
,
String
key
,
int
type
)
{
boolean
lock
=
false
;
if
(
ObjectUtils
.
isEmpty
(
waitTime
))
{
waitTime
=
WAITTIME
;
}
if
(
ObjectUtils
.
isEmpty
(
releaseTime
))
{
releaseTime
=
RELEASETIME
;
}
try
{
RLock
rLock
=
getLockByKey
(
key
,
type
);
lock
=
rLock
.
tryLock
(
waitTime
,
releaseTime
,
TimeUnit
.
MILLISECONDS
);
if
(!
lock
)
{
log
.
error
(
"分布式锁加锁:{}失败,请重新尝试"
);
throw
new
RedissonException
(
RedissonErrorCode
.
METHOD_IN_EXECUTION
);
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
lock
;
}
/**
* 手动释放 redissonLock 锁
*
* @param key
* @return
*/
public
boolean
releaseLock
(
String
key
,
int
type
)
{
String
threadName
=
Thread
.
currentThread
().
getName
()
+
":"
+
Thread
.
currentThread
().
getId
();
try
{
RLock
rLock
=
getLockByKey
(
key
,
type
);
rLock
.
unlock
();
if
(!
rLock
.
isLocked
())
{
log
.
debug
(
"已删除锁{}成功,当前线程:{}"
,
key
,
threadName
);
return
true
;
}
else
if
(
rLock
.
isHeldByCurrentThread
())
{
log
.
debug
(
"未删除锁{},还需当前线程解锁{}次,当前线程:{}"
,
key
,
rLock
.
getHoldCount
(),
threadName
);
return
true
;
}
else
{
log
.
warn
(
"未删除锁{},还需其他线程解锁{}次,当前线程:{}"
,
key
,
rLock
.
getHoldCount
(),
threadName
);
return
false
;
}
}
catch
(
Throwable
e
)
{
log
.
error
(
"解锁{}异常,返回false,当前线程:{}"
,
key
,
threadName
,
e
);
return
false
;
}
}
}
src/test/java/com/mushiny/redisson/MwmsRedissonApplicationTests.java
0 → 100644
View file @
8f09d46a
package
com
.
mushiny
.
redisson
;
import
org.junit.jupiter.api.Test
;
import
org.springframework.boot.test.context.SpringBootTest
;
@SpringBootTest
class
MwmsRedissonApplicationTests
{
@Test
void
contextLoads
()
{
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment