提交 2d8b66e2 编写于 作者: zlt2000's avatar zlt2000

分布式锁的实现方式改为Redisson,并优化抽象接口

上级 4be31c40
......@@ -61,7 +61,7 @@ public class SysRoleController {
* @return
*/
@PostMapping("/roles/saveOrUpdate")
public Result saveOrUpdate(@RequestBody SysRole sysRole) {
public Result saveOrUpdate(@RequestBody SysRole sysRole) throws Exception {
return sysRoleService.saveOrUpdateRole(sysRole);
}
......
......@@ -19,6 +19,8 @@ import com.central.search.model.LogicDelDto;
import com.central.search.model.SearchDto;
import com.central.user.model.SysUserExcel;
import org.apache.commons.collections4.MapUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
......@@ -57,6 +59,9 @@ public class SysUserController {
@Autowired
private IQueryService queryService;
@Autowired
private RedissonClient redisson;
/**
* 当前登录用户 LoginAppUser
*
......@@ -65,6 +70,9 @@ public class SysUserController {
@ApiOperation(value = "根据access_token当前登录用户")
@GetMapping("/users/current")
public Result<LoginAppUser> getLoginAppUser(@LoginUser(isFull = true) SysUser user) {
RLock lock = redisson.getLock("test");
lock.lock();
return Result.succeed(appUserService.getLoginAppUser(user));
}
......@@ -236,7 +244,7 @@ public class SysUserController {
@CacheEvict(value = "user", key = "#sysUser.username")
@PostMapping("/users/saveOrUpdate")
@AuditLog(operation = "'新增或更新用户:' + #sysUser.username")
public Result saveOrUpdate(@RequestBody SysUser sysUser) {
public Result saveOrUpdate(@RequestBody SysUser sysUser) throws Exception {
return appUserService.saveOrUpdateUser(sysUser);
}
......
......@@ -9,10 +9,13 @@ import com.central.common.model.SysRole;
import com.central.common.service.ISuperService;
/**
* @author zlt
* @author zlt
* <p>
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
public interface ISysRoleService extends ISuperService<SysRole> {
void saveRole(SysRole sysRole);
void saveRole(SysRole sysRole) throws Exception;
void deleteRole(Long id);
......@@ -28,7 +31,7 @@ public interface ISysRoleService extends ISuperService<SysRole> {
* @param sysRole
* @return Result
*/
Result saveOrUpdateRole(SysRole sysRole);
Result saveOrUpdateRole(SysRole sysRole) throws Exception;
/**
* 查询所有角色
......
......@@ -13,7 +13,10 @@ import com.central.common.model.SysRole;
import com.central.common.model.SysUser;
/**
* @author zlt
* @author zlt
* <p>
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
public interface ISysUserService extends ISuperService<SysUser> {
/**
......@@ -98,7 +101,7 @@ public interface ISysUserService extends ISuperService<SysUser> {
*/
List<SysUserExcel> findAllUsers(Map<String, Object> params);
Result saveOrUpdateUser(SysUser sysUser);
Result saveOrUpdateUser(SysUser sysUser) throws Exception;
/**
* 删除用户
......
......@@ -29,7 +29,7 @@ import javax.annotation.Resource;
@Slf4j
@Service
public class SysRoleServiceImpl extends SuperServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {
private final static String LOCK_KEY_ROLECODE = CommonConstant.LOCK_KEY_PREFIX+"rolecode:";
private final static String LOCK_KEY_ROLECODE = "rolecode:";
@Resource
private SysUserRoleMapper userRoleMapper;
......@@ -42,7 +42,7 @@ public class SysRoleServiceImpl extends SuperServiceImpl<SysRoleMapper, SysRole>
@Transactional(rollbackFor = Exception.class)
@Override
public void saveRole(SysRole sysRole) {
public void saveRole(SysRole sysRole) throws Exception {
String roleCode = sysRole.getCode();
super.saveIdempotency(sysRole, lock
, LOCK_KEY_ROLECODE+roleCode, new QueryWrapper<SysRole>().eq("code", roleCode), "角色code已存在");
......@@ -67,7 +67,7 @@ public class SysRoleServiceImpl extends SuperServiceImpl<SysRoleMapper, SysRole>
@Override
@Transactional
public Result saveOrUpdateRole(SysRole sysRole) {
public Result saveOrUpdateRole(SysRole sysRole) throws Exception {
if (sysRole.getId() == null) {
this.saveRole(sysRole);
} else {
......
......@@ -37,7 +37,7 @@ import javax.annotation.Resource;
@Slf4j
@Service
public class SysUserServiceImpl extends SuperServiceImpl<SysUserMapper, SysUser> implements ISysUserService {
private final static String LOCK_KEY_USERNAME = CommonConstant.LOCK_KEY_PREFIX+"username:";
private final static String LOCK_KEY_USERNAME = "username:";
@Autowired
private PasswordEncoder passwordEncoder;
......@@ -219,7 +219,7 @@ public class SysUserServiceImpl extends SuperServiceImpl<SysUserMapper, SysUser>
@Transactional(rollbackFor = Exception.class)
@Override
public Result saveOrUpdateUser(SysUser sysUser) {
public Result saveOrUpdateUser(SysUser sysUser) throws Exception {
if (sysUser.getId() == null) {
if (StringUtils.isBlank(sysUser.getType())) {
sysUser.setType(UserType.BACKEND.name());
......
package com.central.user.service;
import com.central.common.lock.DistributedLock;
import com.central.common.model.LoginAppUser;
import static org.assertj.core.api.Assertions.*;
......@@ -7,12 +8,14 @@ import com.central.common.model.PageResult;
import com.central.common.model.SysUser;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* SysUserServiceTest单元测试用例
......@@ -25,6 +28,20 @@ public class SysUserServiceTest {
@Autowired
private ISysUserService sysUserService;
@Autowired
private DistributedLock locker;
@Test
public void testLock() throws Exception {
Object lock = null;
try {
lock = locker.tryLock("test", 1000, TimeUnit.MILLISECONDS, true);
Thread.sleep(5000);
} finally {
locker.unlock(lock);
}
}
@Test
public void testFindByUsername() {
LoginAppUser loginAppUser = sysUserService.findByUsername("admin");
......
package com.central.common.lock;
/**
* 分布式锁抽象类
*
* @author zlt
* @date 2018/5/29 14:14
*/
public abstract class AbstractDistributedLock implements DistributedLock{
@Override
public boolean lock(String key) {
return lock(key, TIMEOUT_MILLIS, RETRY_TIMES, SLEEP_MILLIS);
}
@Override
public boolean lock(String key, int retryTimes) {
return lock(key, TIMEOUT_MILLIS, retryTimes, SLEEP_MILLIS);
}
@Override
public boolean lock(String key, int retryTimes, long sleepMillis) {
return lock(key, TIMEOUT_MILLIS, retryTimes, sleepMillis);
}
@Override
public boolean lock(String key, long expire) {
return lock(key, expire, RETRY_TIMES, SLEEP_MILLIS);
}
@Override
public boolean lock(String key, long expire, int retryTimes) {
return lock(key, expire, retryTimes, SLEEP_MILLIS);
}
}
package com.central.common.lock;
import java.util.concurrent.TimeUnit;
/**
* 分布式锁顶级接口
* 例如:
* RETRY_TIMES=100,SLEEP_MILLIS=100
* RETRY_TIMES * SLEEP_MILLIS = 10000 意味着如果一直获取不了锁,最长会等待10秒后抛超时异常
*
* @author zlt
* @date 2018/5/29 14:12
* <p>
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
public interface DistributedLock {
/**
* 默认超时时间
*/
long TIMEOUT_MILLIS = 5000;
/**
* 重试次数
*/
int RETRY_TIMES = 100;
/**
* 每次重试后等待的时间
*/
long SLEEP_MILLIS = 100;
/**
* 获取锁
*
* @param key key
* @return 成功/失败
*/
boolean lock(String key);
/**
* 获取锁
*
* @param key key
* @param retryTimes 重试次数
* @return 成功/失败
*/
boolean lock(String key, int retryTimes);
/**
* 获取锁
*
* @param key key
* @param retryTimes 重试次数
* @param sleepMillis 获取锁失败的重试间隔
* @return 成功/失败
*/
boolean lock(String key, int retryTimes, long sleepMillis);
/**
* 获取锁
*
* @param key key
* @param expire 获取锁超时时间
* @return 成功/失败
*/
boolean lock(String key, long expire);
/**
* 获取锁
*
* @param key key
* @param expire 获取锁超时时间
* @param retryTimes 重试次数
* @return 成功/失败
* 获取锁,如果获取不成功则一直等待直到lock被获取
* @param key 锁的key
* @param leaseTime 加锁的时间,超过这个时间后锁便自动解锁;
* 如果leaseTime为-1,则保持锁定直到显式解锁
* @param unit {@code leaseTime} 参数的时间单位
* @param isFair 是否公平锁
* @return 锁对象
*/
boolean lock(String key, long expire, int retryTimes);
Object lock(String key, long leaseTime, TimeUnit unit, boolean isFair) throws Exception;
Object lock(String key, long leaseTime, TimeUnit unit) throws Exception;
Object lock(String key, boolean isFair) throws Exception;
Object lock(String key) throws Exception;
/**
* 获取锁
*
* @param key key
* @param expire 获取锁超时时间
* @param retryTimes 重试次数
* @param sleepMillis 获取锁失败的重试间隔
* @return 成功/失败
* 尝试获取锁,如果锁不可用则等待最多waitTime时间后放弃
* @param key 锁的key
* @param waitTime 获取锁的最大尝试时间(单位毫秒)
* @param leaseTime 加锁的时间,超过这个时间后锁便自动解锁;
* 如果leaseTime为-1,则保持锁定直到显式解锁
* @param unit {@code waitTime} 和 {@code leaseTime} 参数的时间单位
* @return 锁对象,如果获取锁失败则为null
*/
boolean lock(String key, long expire, int retryTimes, long sleepMillis);
Object tryLock(String key, long waitTime, long leaseTime, TimeUnit unit, boolean isFair) throws Exception;
Object tryLock(String key, long waitTime, long leaseTime, TimeUnit unit) throws Exception;
Object tryLock(String key, long waitTime, TimeUnit unit, boolean isFair) throws Exception;
Object tryLock(String key, long waitTime, TimeUnit unit) throws Exception;
/**
* 释放锁
*
* @param key key值
* @return 释放结果
* @param lock 锁对象
*/
boolean releaseLock(String key);
void unlock(Object lock) throws Exception;
}
......@@ -9,51 +9,46 @@ import com.central.common.lock.DistributedLock;
*
* @author zlt
* @date 2019/1/10
* <p>
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
public interface ISuperService<T> extends IService<T> {
/**
* 幂等性新增记录
* 例子如下:
* String username = sysUser.getUsername();
* boolean result = super.saveIdempotency(sysUser, lock
* , LOCK_KEY_USERNAME+username
* , new QueryWrapper<SysUser>().eq("username", username));
*
* @param entity 实体对象
* @param lock 锁实例
* @param locker 锁实例
* @param lockKey 锁的key
* @param countWrapper 判断是否存在的条件
* @param msg 对象已存在提示信息
* @return
*/
boolean saveIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper<T> countWrapper, String msg);
boolean saveIdempotency(T entity, DistributedLock locker, String lockKey, Wrapper<T> countWrapper, String msg) throws Exception;
/**
* 幂等性新增记录
*
* @param entity 实体对象
* @param lock 锁实例
* @param lockKey 锁的key
* @param countWrapper 判断是否存在的条件
* @return
*/
boolean saveIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper<T> countWrapper);
boolean saveIdempotency(T entity, DistributedLock locker, String lockKey, Wrapper<T> countWrapper) throws Exception;
/**
* 幂等性新增或更新记录
* 例子如下:
* String username = sysUser.getUsername();
* boolean result = super.saveOrUpdateIdempotency(sysUser, lock
* , LOCK_KEY_USERNAME+username
* , new QueryWrapper<SysUser>().eq("username", username));
*
* @param entity 实体对象
* @param lock 锁实例
* @param locker 锁实例
* @param lockKey 锁的key
* @param countWrapper 判断是否存在的条件
* @param msg 对象已存在提示信息
* @return
*/
boolean saveOrUpdateIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper<T> countWrapper, String msg);
boolean saveOrUpdateIdempotency(T entity, DistributedLock locker, String lockKey, Wrapper<T> countWrapper, String msg) throws Exception;
/**
* 幂等性新增或更新记录
*
* @param entity 实体对象
* @param lock 锁实例
* @param lockKey 锁的key
* @param countWrapper 判断是否存在的条件
* @return
*/
boolean saveOrUpdateIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper<T> countWrapper);
boolean saveOrUpdateIdempotency(T entity, DistributedLock locker, String lockKey, Wrapper<T> countWrapper) throws Exception;
}
......@@ -16,41 +16,31 @@ import com.central.common.service.ISuperService;
import java.io.Serializable;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* service实现父类
*
* @author zlt
* @date 2019/1/10
* <p>
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
public class SuperServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> implements ISuperService<T> {
/**
* 幂等性新增记录
* 例子如下:
* String username = sysUser.getUsername();
* boolean result = super.saveIdempotency(sysUser, lock
* , LOCK_KEY_USERNAME+username
* , new QueryWrapper<SysUser>().eq("username", username));
*
* @param entity 实体对象
* @param lock 锁实例
* @param lockKey 锁的key
* @param countWrapper 判断是否存在的条件
* @param msg 对象已存在提示信息
* @return
*/
@Override
public boolean saveIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper<T> countWrapper, String msg) {
if (lock == null) {
public boolean saveIdempotency(T entity, DistributedLock locker, String lockKey, Wrapper<T> countWrapper, String msg) throws Exception {
if (locker == null) {
throw new LockException("DistributedLock is null");
}
if (StrUtil.isEmpty(lockKey)) {
throw new LockException("lockKey is null");
}
Object lock;
try {
//加锁
boolean isLock = lock.lock(lockKey);
if (isLock) {
lock = locker.tryLock(lockKey, 10, 60, TimeUnit.SECONDS);
if (lock != null) {
//判断记录是否已存在
int count = super.count(countWrapper);
if (count == 0) {
......@@ -65,41 +55,17 @@ public class SuperServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M,
throw new LockException("锁等待超时");
}
} finally {
lock.releaseLock(lockKey);
locker.unlock(lockKey);
}
}
/**
* 幂等性新增记录
*
* @param entity 实体对象
* @param lock 锁实例
* @param lockKey 锁的key
* @param countWrapper 判断是否存在的条件
* @return
*/
@Override
public boolean saveIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper<T> countWrapper) {
public boolean saveIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper<T> countWrapper) throws Exception {
return saveIdempotency(entity, lock, lockKey, countWrapper, null);
}
/**
* 幂等性新增或更新记录
* 例子如下:
* String username = sysUser.getUsername();
* boolean result = super.saveOrUpdateIdempotency(sysUser, lock
* , LOCK_KEY_USERNAME+username
* , new QueryWrapper<SysUser>().eq("username", username));
*
* @param entity 实体对象
* @param lock 锁实例
* @param lockKey 锁的key
* @param countWrapper 判断是否存在的条件
* @param msg 对象已存在提示信息
* @return
*/
@Override
public boolean saveOrUpdateIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper<T> countWrapper, String msg) {
public boolean saveOrUpdateIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper<T> countWrapper, String msg) throws Exception {
if (null != entity) {
Class<?> cls = entity.getClass();
TableInfo tableInfo = TableInfoHelper.getTableInfo(cls);
......@@ -120,22 +86,8 @@ public class SuperServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M,
return false;
}
/**
* 幂等性新增或更新记录
* 例子如下:
* String username = sysUser.getUsername();
* boolean result = super.saveOrUpdateIdempotency(sysUser, lock
* , LOCK_KEY_USERNAME+username
* , new QueryWrapper<SysUser>().eq("username", username));
*
* @param entity 实体对象
* @param lock 锁实例
* @param lockKey 锁的key
* @param countWrapper 判断是否存在的条件
* @return
*/
@Override
public boolean saveOrUpdateIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper<T> countWrapper) {
public boolean saveOrUpdateIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper<T> countWrapper) throws Exception {
return this.saveOrUpdateIdempotency(entity, lock, lockKey, countWrapper, null);
}
}
package com.central.common.redis.lock;
import com.central.common.lock.AbstractDistributedLock;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.stereotype.Component;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
......@@ -18,9 +17,16 @@ import java.util.concurrent.TimeUnit;
*
* @author zlt
* @date 2018/5/29 14:16
* <p>
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*
* @deprecated 建议使用Redisson的实现方式 {@link RedissonDistributedLock}
*/
@Slf4j
public class RedisDistributedLock extends AbstractDistributedLock {
@ConditionalOnClass(RedisTemplate.class)
@Deprecated
public class RedisDistributedLock {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
......@@ -45,7 +51,15 @@ public class RedisDistributedLock extends AbstractDistributedLock {
this.redisTemplate = redisTemplate;
}
@Override
/**
* 获取锁
*
* @param key 锁的key
* @param expire 获取锁超时时间
* @param retryTimes 重试次数
* @param sleepMillis 获取锁失败的重试间隔
* @return 成功/失败
*/
public boolean lock(String key, long expire, int retryTimes, long sleepMillis) {
boolean result = setRedis(key, expire);
// 如果获取锁失败,按照传入的重试次数进行重试
......@@ -79,7 +93,11 @@ public class RedisDistributedLock extends AbstractDistributedLock {
return false;
}
@Override
/**
* 释放锁
* @param key 锁的key
* @return 成功/失败
*/
public boolean releaseLock(String key) {
// 释放锁的时候,有可能因为持锁之后方法执行时间大于锁的有效期,此时有可能已经被另外一个线程持有锁,所以不能直接删除
try {
......
package com.central.common.redis.lock;
import com.central.common.constant.CommonConstant;
import com.central.common.exception.LockException;
import com.central.common.lock.DistributedLock;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import java.util.concurrent.TimeUnit;
/**
* redisson分布式锁实现,基本锁功能的抽象实现
* 本接口能满足绝大部分的需求,高级的锁功能,请自行扩展或直接使用原生api
*
* @author zlt
* @date 2020/5/5
* <p>
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@ConditionalOnClass(RedissonClient.class)
public class RedissonDistributedLock implements DistributedLock {
@Autowired
private RedissonClient redisson;
private RLock getLock(String key, boolean isFair) {
if (isFair) {
return redisson.getFairLock(CommonConstant.LOCK_KEY_PREFIX + key);
}
return redisson.getLock(CommonConstant.LOCK_KEY_PREFIX + key);
}
@Override
public RLock lock(String key, long leaseTime, TimeUnit unit, boolean isFair) {
RLock lock = getLock(key, isFair);
lock.lock(leaseTime, unit);
return lock;
}
@Override
public RLock lock(String key, long leaseTime, TimeUnit unit) {
return lock(key, leaseTime, unit, false);
}
@Override
public RLock lock(String key, boolean isFair) {
return lock(key, -1, null, isFair);
}
@Override
public RLock lock(String key) {
return lock(key, -1, null, false);
}
@Override
public RLock tryLock(String key, long waitTime, long leaseTime, TimeUnit unit, boolean isFair) throws InterruptedException {
RLock lock = getLock(key, isFair);
if (lock.tryLock(waitTime, leaseTime, unit)) {
return lock;
}
return null;
}
@Override
public RLock tryLock(String key, long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {
return tryLock(key, waitTime, leaseTime, unit, false);
}
@Override
public RLock tryLock(String key, long waitTime, TimeUnit unit, boolean isFair) throws InterruptedException {
return tryLock(key, waitTime, -1, unit, isFair);
}
@Override
public RLock tryLock(String key, long waitTime, TimeUnit unit) throws InterruptedException {
return tryLock(key, waitTime, -1, unit, false);
}
@Override
public void unlock(Object lock) {
if (lock != null) {
if (lock instanceof RLock) {
RLock rLock = (RLock)lock;
if (rLock.isLocked()) {
rLock.unlock();
}
} else {
throw new LockException("requires RLock type");
}
}
}
}
package com.central.common.redis.util;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.serializer.support.DeserializingConverter;
import org.springframework.core.serializer.support.SerializingConverter;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
/**
* 此时定义的序列化操作表示可以序列化所有类的对象,当然,这个对象所在的类一定要实现序列化接口
*
* @author zlt
*/
public class RedisObjectSerializer implements RedisSerializer<Object> {
// 做一个空数组,不是null
private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
// 为了方便进行对象与字节数组的转换,所以应该首先准备出两个转换器
private Converter<Object, byte[]> serializingConverter = new SerializingConverter();
private Converter<byte[], Object> deserializingConverter = new DeserializingConverter();
@Override
public byte[] serialize(Object obj) {
// 这个时候没有要序列化的对象出现,所以返回的字节数组应该就是一个空数组
if (obj == null) {
return EMPTY_BYTE_ARRAY;
}
// 将对象变为字节数组
return this.serializingConverter.convert(obj);
}
@Override
public Object deserialize(byte[] data) {
// 此时没有对象的内容信息
if (data == null || data.length == 0) {
return null;
}
return this.deserializingConverter.convert(data);
}
}
\ No newline at end of file
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.central.common.redis.RedisAutoConfigure,\
com.central.common.redis.lock.RedisDistributedLock,\
com.central.common.redis.lock.RedissonDistributedLock,\
com.central.common.redis.template.RedisRepository
\ No newline at end of file
......@@ -18,6 +18,9 @@ import java.util.Map;
* 应用相关接口
*
* @author zlt
* <p>
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Api(tags = "应用")
@RestController
......@@ -53,7 +56,7 @@ public class ClientController {
@PostMapping("/saveOrUpdate")
@ApiOperation(value = "保存或者修改应用")
public Result saveOrUpdate(@RequestBody ClientDto clientDto) {
public Result saveOrUpdate(@RequestBody ClientDto clientDto) throws Exception {
return clientService.saveClient(clientDto);
}
}
......@@ -9,9 +9,12 @@ import java.util.Map;
/**
* @author zlt
* <p>
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
public interface IClientService extends ISuperService<Client> {
Result saveClient(Client clientDto);
Result saveClient(Client clientDto) throws Exception;
/**
* 查询应用列表
......
......@@ -23,11 +23,14 @@ import java.util.Map;
/**
* @author zlt
* <p>
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Slf4j
@Service
public class ClientServiceImpl extends SuperServiceImpl<ClientMapper, Client> implements IClientService {
private final static String LOCK_KEY_CLIENTID = CommonConstant.LOCK_KEY_PREFIX+"clientId:";
private final static String LOCK_KEY_CLIENTID = "clientId:";
@Autowired
private RedisRepository redisRepository;
......@@ -39,7 +42,7 @@ public class ClientServiceImpl extends SuperServiceImpl<ClientMapper, Client> im
private DistributedLock lock;
@Override
public Result saveClient(Client client) {
public Result saveClient(Client client) throws Exception {
client.setClientSecret(passwordEncoder.encode(client.getClientSecretStr()));
String clientId = client.getClientId();
super.saveOrUpdateIdempotency(client, lock
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册