diff --git a/README.md b/README.md index 6f04c601e6fe149a103bcc264f5ec14403f916fc..b9a1b62b5fcaa47c0be31187d7bbbaf95b364b27 100644 --- a/README.md +++ b/README.md @@ -432,35 +432,56 @@ FOREIGN_KEY_CHECKS = 1; | resource | varchar(40) | 雪花算法随机UUID | | desc | varchar(200) | 功能描述 | | env | varchar(200) | 环境 | +| create_time | datetime | 资源锁定时间 | - 加锁的实现如下,比较简单的实现,一般分布式锁实现都是使用Redis等 ```java -@Service public class LockServiceImpl implements LockService { - - private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(LockServiceImpl.class); - - @Resource private LockMapper lockMapper; - - @Override public Long acquire(String key) { - try { - LockDO lockDO = new LockDO(); - lockDO.setResource(key); - lockDO.setDesc(key); - lockDO.setEnv(EnvUtils.getEnv()); - lockMapper.insert(lockDO); - return lockDO.getId(); - } catch (DuplicateKeyException ex) { - LOGGER.warn("[LockService][acquire] lock acquire error:{}", ThrowableUtil.stackTraceToString(ex)); - } - return null; +@Service +public class LockServiceImpl implements LockService { + + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(LockServiceImpl.class); + + @Resource + private LockMapper lockMapper; + + private static final int TIMEOUT = 3000; + + @Override + public Long acquire(String key) { + // 查询 + String env = EnvUtils.getEnv(); + LockDO oldLock = lockMapper.queryByResource(key, env); + if (oldLock != null) { + if (System.currentTimeMillis() - oldLock.getCreateTime().getTime() > TIMEOUT) { + release(key, oldLock.getId()); + } + return null; } - @Override public boolean release(String key, Long lockId) { - return lockMapper.delete(lockId, key, EnvUtils.getEnv()) > 0; + try { + LockDO lockDO = new LockDO(); + lockDO.setResource(key); + lockDO.setDesc(key); + lockDO.setEnv(env); + lockDO.setCreateTime(new Date()); + lockMapper.insert(lockDO); + return lockDO.getId(); + } catch (DuplicateKeyException ex) { + LOGGER.warn("[LockService][acquire][DuplicateKeyException] lock acquire error:{}", ThrowableUtil.stackTraceToString(ex)); + } catch (Exception ex) { + LOGGER.warn("[LockService][acquire][Exception] lock acquire error:{}", ThrowableUtil.stackTraceToString(ex)); } + return null; + } + + @Override + public boolean release(String key, Long lockId) { + return lockMapper.delete(lockId, key, EnvUtils.getEnv()) > 0; + } } + ``` ## 项目界面 diff --git a/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/impl/LockServiceImpl.java b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/impl/LockServiceImpl.java index 13c5c277bddea6492a81d354e02a015902e85bd2..2765f10c029038daa865538648d6fa0ff6d34d3c 100644 --- a/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/impl/LockServiceImpl.java +++ b/admin/admin-biz/src/main/java/cn/icanci/loopstack/ddk/admin/biz/service/impl/LockServiceImpl.java @@ -6,6 +6,8 @@ import cn.icanci.loopstack.ddk.admin.dal.mapper.entity.LockDO; import cn.icanci.loopstack.ddk.admin.dal.mapper.mapper.LockMapper; import io.netty.util.internal.ThrowableUtil; +import java.util.Date; + import javax.annotation.Resource; import org.slf4j.LoggerFactory; @@ -19,22 +21,37 @@ import org.springframework.stereotype.Service; @Service public class LockServiceImpl implements LockService { - private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(LockServiceImpl.class); + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(LockServiceImpl.class); @Resource private LockMapper lockMapper; + private static final int TIMEOUT = 3000; + @Override public Long acquire(String key) { + // 查询 + String env = EnvUtils.getEnv(); + LockDO oldLock = lockMapper.queryByResource(key, env); + if (oldLock != null) { + if (System.currentTimeMillis() - oldLock.getCreateTime().getTime() > TIMEOUT) { + release(key, oldLock.getId()); + } + return null; + } + try { LockDO lockDO = new LockDO(); lockDO.setResource(key); lockDO.setDesc(key); - lockDO.setEnv(EnvUtils.getEnv()); + lockDO.setEnv(env); + lockDO.setCreateTime(new Date()); lockMapper.insert(lockDO); return lockDO.getId(); } catch (DuplicateKeyException ex) { - LOGGER.warn("[LockService][acquire] lock acquire error:{}", ThrowableUtil.stackTraceToString(ex)); + LOGGER.warn("[LockService][acquire][DuplicateKeyException] lock acquire error:{}", ThrowableUtil.stackTraceToString(ex)); + } catch (Exception ex) { + LOGGER.warn("[LockService][acquire][Exception] lock acquire error:{}", ThrowableUtil.stackTraceToString(ex)); } return null; } diff --git a/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/entity/LockDO.java b/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/entity/LockDO.java index 1c35034cd8669ea4c0bdecbbd3c8de679de0bfef..6e981d440d3468c1680725e5876d9c803645eade 100644 --- a/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/entity/LockDO.java +++ b/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/entity/LockDO.java @@ -2,8 +2,6 @@ package cn.icanci.loopstack.ddk.admin.dal.mapper.entity; import java.io.Serializable; import java.util.Date; -import java.util.List; -import java.math.BigDecimal; /** * DdkLock @@ -31,6 +29,11 @@ public class LockDO implements Serializable { */ private String desc; + /** + * createTime 创建时间 + */ + private Date createTime; + /** * env 环境 */ @@ -67,4 +70,12 @@ public class LockDO implements Serializable { public String getEnv() { return this.env; } + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } } \ No newline at end of file diff --git a/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/mapper/LockMapper.java b/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/mapper/LockMapper.java index 61be5ebdf3d8593d247f2d8dd90ebe45ace59ba0..b2ce0c811d3abcb8c0a6b92b7b8dbb86daa67d09 100644 --- a/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/mapper/LockMapper.java +++ b/admin/admin-dal/src/main/java/cn/icanci/loopstack/ddk/admin/dal/mapper/mapper/LockMapper.java @@ -29,4 +29,6 @@ public interface LockMapper { * @param resource 资源 **/ int delete(@Param("key") Object key, @Param("resource") String resource, @Param("env") String env); + + LockDO queryByResource(@Param("resource") String resource, @Param("env") String env); } diff --git a/admin/admin-dal/src/main/resources/mybatis/mapper/LockMapper.xml b/admin/admin-dal/src/main/resources/mybatis/mapper/LockMapper.xml index e0d170d6cd79c873f06480f937a28228ed2e5e2e..f0a8fc37328fda9f31f032814667200b173a5327 100644 --- a/admin/admin-dal/src/main/resources/mybatis/mapper/LockMapper.xml +++ b/admin/admin-dal/src/main/resources/mybatis/mapper/LockMapper.xml @@ -9,6 +9,7 @@ + @@ -16,7 +17,8 @@ , `resource`, `desc`, - `env` + `env`, + `create_time` @@ -60,5 +62,11 @@ and `env` = #{env} and `resource` = #{resource} + \ No newline at end of file