目录
一:框架集成
1.添加pom依赖
2.开启lock配置
二:配置详细介绍
1.配置清单
2.具体配置介绍
(1)implementer
(2)type
(3)transactionStrategy
(4)lockFailStrategy
(5)lockExceptionStrategy
(6)releaseTimeoutStrategy
三:CUSTOMER的SPI扩展示例
1.SPI扩展点
2.使用示例
四:代码示例
1.代码方式
2:注解方式示例
(1).方法头部同时存在@Transactional及@Lock时
(2).@LockKey的使用
(3).快捷注解的使用
4().自定义快速失败时,抛出的异常类型及异常信息(可单独设置)
(5).定制上锁失败策略
一:框架集成
1.添加pom依赖
|
2.开启lock配置
目前分布式锁仅支持redis实现
application.yml示例:
|
application.properties示例:
|
如遇到集成问题,可联系@苏友良
二:配置详细介绍
1.配置清单
配置名 | 配置简介 | 默认值 | 作用域 | 其他 |
---|---|---|---|---|
enable | 是否开启 | Boolean.FALSE | 全局 | 使用需开启此配置 |
implementer | lock厂商实现类型 | LockImplementer.REDIS | 全局及注解 | redis实现 |
type | lock 的类型 | LockType.Reentrant | 全局及注解 | |
keys | 自定义业务key(支持SpingEL) | 无 | 注解 | 系统会按照${name}:${key1}:...:${keyN}:${@LockKey1}:...:${@LockKeyN}的方式拼接,作为lock的key 特殊的:当name,keys以及注解@LockKey都为空时,系统默认使用方法的全限定类名作为key(不推荐使用此方式) |
name | 锁的名称 | 无 | 注解 | 系统会按照${name}:${key1}:...:${keyN}:${@LockKey1}:...:${@LockKeyN}的方式拼接,作为lock的key 特殊的:当name,keys以及注解@LockKey都为空时,系统默认使用方法的全限定类名作为key(不推荐使用此方式) |
supportTransaction | 是否支持上下文感知 | Boolean.TRUE | 全局及注解 | |
withLocalCache | 是否支持本地lock二级缓存 | Boolean.FALSE | 全局及注解 | |
transactionStrategy | 仅开启supportTransaction生效 | LockTransactionStrategy.WARMING | 全局 | 打warm日志 |
waitTime | 等待时间 | 2s | 全局及注解 | |
leaseTime | 等待时间 | 60s | 全局及注解 | 此参数在Lock官方定义中不生效,可通过自定义LockAdapter使用该参数。redis实现中默认此参数不生效(自动续期机制),如方言需使用此参数参考:cn.techwolf.blue.usl.framework.lock.factory.support.RedissonLockAdapterFactory |
lockFailStrategy | 加锁失败的处理策略 | FailOnLockStrategy.FAIL_FAST | 全局及注解 | 快速失败 |
exceptionOnLockStrategy | 加锁异常的处理策略 | ExceptionOnLockStrategy.THROW_EXCEPTION | 全局及注解 | 抛出异常 |
releaseTimeoutStrategy | 释放锁时异常的处理策略 | ReleaseTimeoutStrategy.FAIL_FAST | 全局及注解 | 快速失败 |
exceptionClass | 获取锁失败时,报错的异常类型 | LockException | 全局及注解 | 获取锁失败时,报错的异常类型 |
exceptionMsg | 获取锁失败时,报错的错误信息 | Failed to acquire Lock(%s) with timeout(%d ms) | 全局及注解 | 仅当LockFailStrategy.FAIL_FAST或者ReleaseTimeoutStrategy.FAIL_FAST生效此处设置二者都会生效 |
customLockFailStrategy | 定制的加锁失败的处理策略 | 无 | 注解 | 用户指定,定义的方法参数需要和注解所在的方法参数保持一致 此方式与lockFailStrategy中的CUSTOM不同点在于:此方式可对方法具体参数做定制化的处理策略, 后者更适合做全局的默认处理 |
customReleaseTimeout Strategy | 定制的释放锁时异常的处理策略 | 无 | 注解 | 用户指定,定义的方法参数需要和注解所在的方法参数保持一致 此方式与releaseTimeoutStrategy中的CUSTOM不同点在于:此方式可对方法具体参数做定制化的处理策略,后者更适合做全局的默认处理 |
注解配置优先级大于全局配置。仅当注解没有配置才会使用全局配置
2.具体配置介绍
(1)implementer
提供的厂商实现:
JVM 本地JVM实现
REDIS
redis实现ZOOKEEPER zookeeper实现
ETCD etcd实现
MYSQL mysql实现
具体见:cn.techwolf.blue.usl.framework.lock.config.LockConfig.LockImplementer
(2)type
lock厂商实现类型:
-
Reentrant 可重入锁
- Fair 公平锁
- Read 读锁
- Write 写锁
- Spin 自旋锁
具体见:cn.techwolf.blue.usl.framework.lock.enums.LockType
(3)transactionStrategy
当lock存在于事务上下文中的策略(仅开启supportTransaction生效):
- WAARMING 打warming日志
- FORBIDDEN 禁止,会抛出异常阻断业务逻辑
- THREAD_SAFE 保证多线程访问安全,unlock会在事务完成后再提交。缺点:会使lock的作用域膨胀。直至上下文事务完成
(4)lockFailStrategy
加锁失败的处理策略:
- NO_OPERATION:继续执行业务逻辑,不做任何处理
- FAIL_FAST:快速失败
- KEEP_ACQUIRE:一直阻塞,直到获得锁,在太多的尝试后,仍会报错
- CUSTOMER: 自定义,用于全局默认处理
(5)lockExceptionStrategy
加锁异常的处理策略:
- THROW_EXCEPTION:抛出异常
- CUSTOMER:自定义,用于全局默认处理
(6)releaseTimeoutStrategy
释放锁时报错的处理策略:
- NO_OPERATION:继续执行业务逻辑,不做任何处理
- FAIL_FAST:快速失败,可自定义异常类及报错信息
- CUSTOMER: 自定义,用于全局默认处理
三:CUSTOMER的SPI扩展示例
1.SPI扩展点
以上的策略中,lockFailStrategy,lockExceptionStrategy,releaseTimeoutStrategy 都提供了CUSTOMER的的策略,框架通过java的SPI机制,将对应的用户自实现的策略加载
策略点 | 策略名 | 具体配置名 | 扩展定义接口 |
---|---|---|---|
加锁失败的处理策略 | lockFailStrategy | CUSTOMER | cn.techwolf.blue.usl.framework.lock.handler.lock.ExceptionOnLockCustomerHandler |
加锁异常的处理策略 | lockExceptionStrategy | CUSTOMER | cn.techwolf.blue.usl.framework.lock.handler.lock.FailOnLockCustomerHandler |
加锁释放锁异常的处理策略 | releaseTimeoutStrategy | CUSTOMER | cn.techwolf.blue.usl.framework.lock.handler.release.ReleaseTimeoutCustomerHandler |
2.使用示例
这里以ExceptionOnLockCustomerHandler 作为示例
(1)在resources文件夹下创建文件夹META-INF/services
(2)在META-INF/services中添加file,名称为扩展的Handler的全限定类名
(3)文件中填写自己基于定义的接口的实现类的全限定类名
自定义处理策略加载后,如果需要指定为全局,需要在全局配置中指定定位的策略名的配置为CUSTOMER即可开启,方法级(或者注解)同理
注意:无论是全局还是注解的方法级,一旦指定以上策略的配置为CUSTOMER,则系统运行时必须存在对应的实现类,否则报错。不同的是,全局级配置报错将导致项目无法启动
四:代码示例
1.代码方式
|
2:注解方式示例
(1).方法头部同时存在@Transactional及@Lock时
|
其中:当方法存在@Transactional时,@Lock方法将在 @Transactional之后执行,即:事务开启前上锁,事务关闭后解锁。与两个注解的上下顺序无关
(2).@LockKey的使用
|
按照${name}:${key1}:...:${keyN}:${@LockKey1}:...:${@LockKeyN}的拼接逻辑 以上示例的key:${userId}:${id}
(3).快捷注解的使用
|
@FailFastLock 快速失败的锁,无需设置等待时间,等待时间为0s
@LocalLock 本地jvm实现的锁
4().自定义快速失败时,抛出的异常类型及异常信息(可单独设置)
|
(5).定制上锁失败策略
如果指定的customLockFailStrategy方法在本类外部,使用全限定名称
|