diff --git a/pom.xml b/pom.xml index bfcbc10..3dd4899 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.yanghuanglin seq - 1.7.2 + 1.8.2 seq seq diff --git a/src/main/java/com/yanghuanglin/seq/config/BaseConfig.java b/src/main/java/com/yanghuanglin/seq/config/BaseConfig.java index 143697f..2cb90c0 100644 --- a/src/main/java/com/yanghuanglin/seq/config/BaseConfig.java +++ b/src/main/java/com/yanghuanglin/seq/config/BaseConfig.java @@ -28,6 +28,8 @@ public class BaseConfig { private Integer step; private String type; private Integer minLength; + private Boolean monthZeroFilling; + private Boolean dayZeroFilling; private BaseConfig() { } @@ -48,10 +50,10 @@ public class BaseConfig { synchronized (BaseConfig.class) { if (instance == null) { instance = new BaseConfig(); + instance.init(generatorConfig); } } } - instance.init(generatorConfig); return instance; } @@ -125,46 +127,47 @@ public class BaseConfig { return minLength; } + public Boolean getMonthZeroFilling() { + if (monthZeroFilling == null) + throw new NullPointerException("请先初始化BaseConfig"); + return monthZeroFilling; + } + + public void setMonthZeroFilling(Boolean monthZeroFilling) { + this.monthZeroFilling = monthZeroFilling; + } + + public Boolean getDayZeroFilling() { + if (dayZeroFilling == null) + throw new NullPointerException("请先初始化BaseConfig"); + return dayZeroFilling; + } + + public void setDayZeroFilling(Boolean dayZeroFilling) { + this.dayZeroFilling = dayZeroFilling; + } + public void setMinLength(Integer minLength) { this.minLength = minLength; } private void init(GeneratorConfig generatorConfig) { - //数据库操作模板 - JdbcTemplate jdbcTemplate = generatorConfig.getJdbcTemplate(); - - if (jdbcTemplate == null) { - //数据源 - DataSource dataSource = generatorConfig.getDataSource(); - if (dataSource == null) - //若数据库操作模板为空,也没有配置数据源,则抛出异常 - throw new NullPointerException("数据源不能为空"); - //否则以数据源创建数据库操作模板 - jdbcTemplate = new JdbcTemplate(dataSource); - } - - if (generatorConfig.getTransactionTemplate() == null) { - //若没有配置事务操作模板,则从配置中取事务管理器 - DataSourceTransactionManager transactionManager = generatorConfig.getTransactionManager(); - if (transactionManager == null) { - //若未配置事务管理器,则通过数据源新建 - DataSource dataSource = jdbcTemplate.getDataSource(); - if (dataSource == null) - throw new NullPointerException("数据源不能为空"); - transactionManager = new DataSourceTransactionManager(dataSource); - } - //通过事务管理器创建事务操作模板 - transactionTemplate = new TransactionTemplate(transactionManager); - } else { - //获取事务操作模板 - transactionTemplate = generatorConfig.getTransactionTemplate(); - } - + //数据源 + DataSource dataSource = generatorConfig.getDataSource(); + if (dataSource == null) + //若数据库操作模板为空,也没有配置数据源,则抛出异常 + throw new NullPointerException("数据源不能为空"); + //否则以数据源创建数据库操作模板 + JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); + DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource); + this.transactionTemplate = new TransactionTemplate(transactionManager); this.sequencesDao = new SequencesDaoImpl(jdbcTemplate, generatorConfig.getTableConfig()); this.sequencesUnusedDao = new SequencesUnusedDaoImpl(jdbcTemplate, generatorConfig.getTableConfig()); this.sequencesUnlockDao = new SequencesUnlockDaoImpl(jdbcTemplate, generatorConfig.getTableConfig()); this.step = generatorConfig.getStep(); this.type = generatorConfig.getType(); this.minLength = generatorConfig.getMinLength(); + this.monthZeroFilling = generatorConfig.getMonthZeroFilling(); + this.dayZeroFilling = generatorConfig.getDayZeroFilling(); } } diff --git a/src/main/java/com/yanghuanglin/seq/config/GeneratorConfig.java b/src/main/java/com/yanghuanglin/seq/config/GeneratorConfig.java index a8757f3..556f85c 100644 --- a/src/main/java/com/yanghuanglin/seq/config/GeneratorConfig.java +++ b/src/main/java/com/yanghuanglin/seq/config/GeneratorConfig.java @@ -1,9 +1,5 @@ package com.yanghuanglin.seq.config; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.datasource.DataSourceTransactionManager; -import org.springframework.transaction.support.TransactionTemplate; - import javax.sql.DataSource; /** @@ -18,21 +14,6 @@ public class GeneratorConfig { */ private DataSource dataSource; - /** - * 数据库操作模板 - */ - private JdbcTemplate jdbcTemplate; - - /** - * 事务处理模板 - */ - private TransactionTemplate transactionTemplate; - - /** - * 事务管理器 - */ - private DataSourceTransactionManager transactionManager; - /** * 自动创建表 */ @@ -51,7 +32,17 @@ public class GeneratorConfig { /** * 默认序号类型 */ - private String type="DEFAULT"; + private String type = "DEFAULT"; + + /** + * 月份是否补零。为false时,1月显示为1,为true时,1月显示为01 + */ + private Boolean monthZeroFilling = true; + + /** + * 日期是否补零。为false时,1日显示为1,为true时,1日显示为01 + */ + private Boolean dayZeroFilling = true; /** * 表和字段配置 @@ -73,30 +64,6 @@ public class GeneratorConfig { this.dataSource = dataSource; } - public JdbcTemplate getJdbcTemplate() { - return jdbcTemplate; - } - - public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { - this.jdbcTemplate = jdbcTemplate; - } - - public TransactionTemplate getTransactionTemplate() { - return transactionTemplate; - } - - public void setTransactionTemplate(TransactionTemplate transactionTemplate) { - this.transactionTemplate = transactionTemplate; - } - - public DataSourceTransactionManager getTransactionManager() { - return transactionManager; - } - - public void setTransactionManager(DataSourceTransactionManager transactionManager) { - this.transactionManager = transactionManager; - } - public Boolean getAutoCreate() { return autoCreate; } @@ -131,6 +98,22 @@ public class GeneratorConfig { this.step = step; } + public Boolean getMonthZeroFilling() { + return monthZeroFilling; + } + + public void setMonthZeroFilling(Boolean monthZeroFilling) { + this.monthZeroFilling = monthZeroFilling; + } + + public Boolean getDayZeroFilling() { + return dayZeroFilling; + } + + public void setDayZeroFilling(Boolean dayZeroFilling) { + this.dayZeroFilling = dayZeroFilling; + } + public TableConfig getTableConfig() { return tableConfig; } diff --git a/src/main/java/com/yanghuanglin/seq/config/TableConfig.java b/src/main/java/com/yanghuanglin/seq/config/TableConfig.java index 05a6e3a..dbac42a 100644 --- a/src/main/java/com/yanghuanglin/seq/config/TableConfig.java +++ b/src/main/java/com/yanghuanglin/seq/config/TableConfig.java @@ -13,7 +13,7 @@ public class TableConfig { private String table = "sequences"; /** - * 序号英文名称,和序号类型组成唯一组件 + * 序号英文名称,和序号类型组成唯一主键 */ private String keyColumn = "key"; diff --git a/src/main/java/com/yanghuanglin/seq/generator/Generator.java b/src/main/java/com/yanghuanglin/seq/generator/Generator.java index 6c316d5..d4c9887 100644 --- a/src/main/java/com/yanghuanglin/seq/generator/Generator.java +++ b/src/main/java/com/yanghuanglin/seq/generator/Generator.java @@ -10,6 +10,14 @@ import com.yanghuanglin.seq.po.SequencesUnused; import java.util.Date; public interface Generator { + /** + * 判断格式定义中是否有序号 + * + * @param pattern 格式 + * @return 是否包含序号 + */ + boolean containSeq(String pattern); + /** * 根据传入的key和type生成可用的序号对象。 *

@@ -18,9 +26,15 @@ public interface Generator { * 如果根据key和默认的{@link GeneratorConfig#getType()}在{@link Sequences}中找到了记录,且在{@link SequencesUnused}也找到了记录,说明该组合生成的序号有部分未使用,返回的是{@link SequencesUnused}中找到的seq最小的序号对象。同时会将{@link SequencesUnused}中找到的seq最小的记录删除,然后写入到{@link SequencesUnlock}中。 *

* - * @param key 数据字典中的编码 + * @param key 数据字典中的编码 + * @param withOutSeq 序号对象不包含序号,其值通过{@link #containSeq(String)}来判断 * @return 可用的序号对象 */ + Sequences generate(String key, Boolean withOutSeq); + + /** + * 同 {@link #generate(String, Boolean)},第二个参数默认为false + */ Sequences generate(String key); /** @@ -31,26 +45,38 @@ public interface Generator { * 如果根据key和type在{@link Sequences}中找到了记录,且在{@link SequencesUnused}也找到了记录,说明该组合生成的序号有部分未使用,返回的是{@link SequencesUnused}中找到的seq最小的序号对象。同时会将{@link SequencesUnused}中找到的seq最小的记录删除,然后写入到{@link SequencesUnlock}中。 *

* - * @param key 数据字典中的编码 - * @param type 序号类型 + * @param key 数据字典中的编码 + * @param type 序号类型 + * @param withOutSeq 序号对象不包含序号,其值通过{@link #containSeq(String)}来判断 * @return 可用的序号对象 */ + Sequences generate(String key, String type, Boolean withOutSeq); + + /** + * 同{@link #generate(String, String, Boolean)},第三个参数默认为false + */ Sequences generate(String key, String type); /** - * 返回根据{@link #generate(String, String)}得到的序号对象,补零后的序号字符串 + * 返回根据{@link #generate(String, String, Boolean)}得到的序号对象,补零后的序号字符串 *

* 如生成的为3,而minLength为5,则返回的是00003 * - * @param key 数据字典中的编码 - * @param type 序号类型 - * @param minLength 序号数字最小长度 + * @param key 数据字典中的编码 + * @param type 序号类型 + * @param minLength 序号数字最小长度 + * @param withOutSeq 序号对象不包含序号,其值通过{@link #containSeq(String)}来判断 * @return 补零后的字符串 */ + String generate(String key, String type, Integer minLength, Boolean withOutSeq); + + /** + * 同{@link #generate(String, String, Integer, Boolean)},第四个参数默认为false + */ String generate(String key, String type, Integer minLength); /** - * 将{@link #generate(String, String)}得到的序号对象格式化为补零后的序号字符串,其最小长度通过{@link BaseConfig#getMinLength()}设定。实际上只会用到{@link Sequences#getSeq()}属性 + * 将{@link #generate(String, String, Boolean)}得到的序号对象格式化为补零后的序号字符串,其最小长度通过{@link BaseConfig#getMinLength()}设定。实际上只会用到{@link Sequences#getSeq()}属性 *

* pattern支持:{@link FormatPlaceholder#YEAR}(当前年份)、{@link FormatPlaceholder#MONTH}}(当前月份)、{@link FormatPlaceholder#DAY}}(当前日期)、{@link FormatPlaceholder#SEQ}}(生成的字符串序号)几个枚举值通过{@link FormatPlaceholder#getPlaceholder()}得到的字符串 * @@ -61,7 +87,7 @@ public interface Generator { String format(Sequences sequences, String pattern); /** - * 将{@link #generate(String, String)}得到的序号对象格式化为补零后的序号字符串。实际上只会用到{@link Sequences#getSeq()}属性 + * 将{@link #generate(String, String, Boolean)}得到的序号对象格式化为补零后的序号字符串。实际上只会用到{@link Sequences#getSeq()}属性 *

* pattern支持:{@link FormatPlaceholder#YEAR}(当前年份)、{@link FormatPlaceholder#MONTH}}(当前月份)、{@link FormatPlaceholder#DAY}}(当前日期)、{@link FormatPlaceholder#SEQ}}(生成的字符串序号)几个枚举值通过{@link FormatPlaceholder#getPlaceholder()}得到的字符串 * @@ -158,7 +184,7 @@ public interface Generator { /** * 锁定指定序号,在序号生成后,调用该序号的逻辑完成后需要执行此方法 *

- * 如办理案件时,先调用{@link #generate(String, String)}或者{@link #generate(String, String, Integer)}生成了序号,之后对案件进行了入库,如果入库完毕,则将该序号锁定,说明这个序号已被使用 + * 如办理案件时,先调用{@link #generate(String, String, Boolean)}或者{@link #generate(String, String, Integer, Boolean)}生成了序号,之后对案件进行了入库,如果入库完毕,则将该序号锁定,说明这个序号已被使用 *

* 注意,此处的锁定非数据库中锁定,而是{@link SequencesUnused}和{@link SequencesUnlock}中均不存在key、type、seq相同的记录视为锁定。因此此处实际是把这两个表中的记录均删除了 * @@ -183,7 +209,7 @@ public interface Generator { *

* {@link SequencesUnlock}中未通过{@link #lock(Sequences)}方法锁定的序号会一直存在,调用此方法会将里面的所有序号都移动到{@link SequencesUnused}中,下次生成序号时优先从{@link SequencesUnused}获取。 */ - void release(); + boolean release(); /** * 释放指定时间段内未使用的序号 @@ -193,7 +219,7 @@ public interface Generator { * @param begin 开始时间 * @param end 结束时间 */ - void release(Date begin, Date end); + boolean release(Date begin, Date end); /** * 释放从开始时间开始,到现在时间之间未使用的序号。结束时间为方法执行时的时间 @@ -214,7 +240,7 @@ public interface Generator { * * @param sequences 需要释放的序号。一般是一个通过{@link Sequences#setKey(String)}、{@link Sequences#setType(String)}、{@link Sequences#setSeq(Long)}三方法一起手动构建或通过{@link Sequences#Sequences(String, String, Long)}构造方法构建的实例对象 */ - void release(Sequences sequences); + boolean release(Sequences sequences); /** * 忽略{@link Sequences#getSeq()}来释放指定序号。一般用于业务对象删除后,对应序号需要回收使用时。 @@ -224,17 +250,17 @@ public interface Generator { * @param sequences 需要释放的序号。一般是一个通过{@link Sequences#setKey(String)}、{@link Sequences#setType(String)}、{@link Sequences#setSeq(Long)}三方法一起手动构建或通过{@link Sequences#Sequences(String, String, Long)}构造方法构建的实例对象 * @param ignoreSeq 是否忽略序号 */ - void release(Sequences sequences, boolean ignoreSeq); + boolean release(Sequences sequences, boolean ignoreSeq); /** * 清空所有闲置序号和未锁定序号 */ - void clear(); + boolean clear(); /** * 清空指定时间段内闲置序号和未锁定序号 */ - void clear(Date begin, Date end); + boolean clear(Date begin, Date end); /** * 清空从开始时间到限制时间之间闲置序号和未锁定序号,结束时间为方法执行时的时间 diff --git a/src/main/java/com/yanghuanglin/seq/generator/impl/SequencesGenerator.java b/src/main/java/com/yanghuanglin/seq/generator/impl/SequencesGenerator.java index 9baa618..b0c7004 100644 --- a/src/main/java/com/yanghuanglin/seq/generator/impl/SequencesGenerator.java +++ b/src/main/java/com/yanghuanglin/seq/generator/impl/SequencesGenerator.java @@ -30,6 +30,8 @@ public class SequencesGenerator implements Generator { private final Integer step; private final String type; private final Integer minLength; + private final Boolean monthZeroFilling; + private final Boolean dayZeroFilling; public SequencesGenerator(GeneratorConfig generatorConfig) { BaseConfig baseConfig = BaseConfig.getInstance(generatorConfig); @@ -41,6 +43,8 @@ public class SequencesGenerator implements Generator { this.step = baseConfig.getStep(); this.type = baseConfig.getType(); this.minLength = baseConfig.getMinLength(); + this.monthZeroFilling = baseConfig.getMonthZeroFilling(); + this.dayZeroFilling = baseConfig.getDayZeroFilling(); createTable(generatorConfig.getAutoCreate()); } @@ -60,47 +64,65 @@ public class SequencesGenerator implements Generator { @Override - public synchronized Sequences generate(String key) { - return generate(key, type); + public boolean containSeq(String pattern) { + return StringUtils.hasLength(pattern) && pattern.contains(SEQ.getPlaceholder()); } @Override - public synchronized Sequences generate(String key, String type) { + public synchronized Sequences generate(String key, Boolean withOutSeq) { + return generate(key, type, withOutSeq); + } + + @Override + public Sequences generate(String key) { + return generate(key, false); + } + + @Override + public synchronized Sequences generate(String key, String type, Boolean withOutSeq) { return transactionTemplate.execute(status -> { try { //根据传入的key和type新生成查询条件对象 Sequences condition = new Sequences(key, type); - //找到正在使用的最大序号 - Sequences sequences = sequencesDao.find(condition); - if (sequences == null) { - //不存在,说明还没生成,将新生成的入库,此时序号为默认的0 - sequences = condition; - sequencesDao.save(sequences); - } + if (!withOutSeq) { + //不是不包含序号的序号对象(有可能格式中只配置了#year##month##day#,序号就不用自增,也不用入库,直接返回即可) + //找到正在使用的最大序号 + Sequences sequences = sequencesDao.find(condition); + boolean result = true; + if (sequences == null) { + //不存在,说明还没生成,将新生成的入库,此时序号为默认的0 + sequences = condition; + result = sequencesDao.save(sequences); + } - //根据传入的key和type查找空闲编号最小的一个 - SequencesUnused conditionIdle = new SequencesUnused(condition); - SequencesUnused sequencesUnused = sequencesUnusedDao.findMinSeq(conditionIdle); + //根据传入的key和type查找空闲编号最小的一个 + SequencesUnused conditionIdle = new SequencesUnused(condition); + SequencesUnused sequencesUnused = sequencesUnusedDao.findMinSeq(conditionIdle); - if (sequencesUnused == null) { - //空闲编号不存在,说明是未生成过,序号需要增加后直接使用,同时将新生成的写入到使用中表 - sequences.increase(step); - SequencesUnlock sequencesUnlock = new SequencesUnlock(sequences); - sequencesUnlock.setCreateTime(new Date()); + if (sequencesUnused == null) { + //空闲编号不存在,说明是未生成过,序号需要增加后直接使用,同时将新生成的写入到使用中表 + sequences.increase(step); + SequencesUnlock sequencesUnlock = new SequencesUnlock(sequences); + sequencesUnlock.setCreateTime(new Date()); - sequencesDao.update(sequences); - sequencesUnlockDao.save(sequencesUnlock); + result = result && sequencesDao.update(sequences) && + sequencesUnlockDao.save(sequencesUnlock); + } else { + //空闲编号存在,说明已经生成过,序号不需要增加,直接使用。同时将该空闲编号移动到使用中表 + sequences = new Sequences(sequencesUnused); + SequencesUnlock sequencesUnlock = new SequencesUnlock(sequencesUnused); + sequencesUnlock.setCreateTime(new Date()); + + result = result && sequencesUnlockDao.save(sequencesUnlock) && + sequencesUnusedDao.delete(sequencesUnused); + } + sequences.setWithOutSeq(false); + return result ? sequences : null; } else { - //空闲编号存在,说明已经生成过,序号不需要增加,直接使用。同时将该空闲编号移动到使用中表 - sequences = new Sequences(sequencesUnused); - SequencesUnlock sequencesUnlock = new SequencesUnlock(sequencesUnused); - sequencesUnlock.setCreateTime(new Date()); - - sequencesUnlockDao.save(sequencesUnlock); - sequencesUnusedDao.delete(sequencesUnused); + condition.setWithOutSeq(true); + return condition; } - return sequences; } catch (Exception e) { e.printStackTrace(); status.setRollbackOnly(); @@ -110,13 +132,23 @@ public class SequencesGenerator implements Generator { } @Override - public synchronized String generate(String key, String type, Integer minLength) { - Sequences sequences = generate(key, type); + public Sequences generate(String key, String type) { + return generate(key, type, false); + } + + @Override + public synchronized String generate(String key, String type, Integer minLength, Boolean withOutSeq) { + Sequences sequences = generate(key, type, withOutSeq); if (sequences == null) return null; return sequences.format(minLength); } + @Override + public String generate(String key, String type, Integer minLength) { + return generate(key, type, minLength, false); + } + @Override public String format(Sequences sequences, String pattern) { return format(sequences, minLength, pattern); @@ -148,9 +180,12 @@ public class SequencesGenerator implements Generator { start = ""; String seqString = start + new Sequences(seq).format(minLength); Calendar calendar = Calendar.getInstance(); - pattern = pattern.replaceAll(YEAR.getPlaceholder(), String.valueOf(calendar.get(Calendar.YEAR))); - pattern = pattern.replaceAll(MONTH.getPlaceholder(), String.format("%02d", calendar.get(Calendar.MONTH) + 1)); - pattern = pattern.replaceAll(DAY.getPlaceholder(), String.valueOf(calendar.get(Calendar.DAY_OF_MONTH))); + int year = calendar.get(Calendar.YEAR); + int month = calendar.get(Calendar.MONTH) + 1; + int day = calendar.get(Calendar.DAY_OF_MONTH); + pattern = pattern.replaceAll(YEAR.getPlaceholder(), String.valueOf(year)); + pattern = pattern.replaceAll(MONTH.getPlaceholder(), monthZeroFilling ? String.format("%02d", month) : String.valueOf(month)); + pattern = pattern.replaceAll(DAY.getPlaceholder(), dayZeroFilling ? String.format("%02d", day) : String.valueOf(day)); pattern = pattern.replaceAll(SEQ.getPlaceholder(), seqString); return pattern; } @@ -228,6 +263,7 @@ public class SequencesGenerator implements Generator { sequences.setMonth(StringUtils.hasLength(month) ? Integer.valueOf(month) : null); sequences.setDay(StringUtils.hasLength(day) ? Integer.valueOf(day) : null); sequences.setSeq(StringUtils.hasLength(seq) ? Long.parseLong(seq) : 0L); + sequences.setWithOutSeq(!StringUtils.hasLength(seq)); sequences.setType(type); return sequences; @@ -235,27 +271,43 @@ public class SequencesGenerator implements Generator { @Override public synchronized boolean lock(Sequences sequences) { - if (sequences == null) + if (sequences == null || sequences.getWithOutSeq()) return true; SequencesUnlock condition = new SequencesUnlock(sequences); //将使用中表的对应数据删除,空闲表中数据在生成时会删除,因此这里不需要处理该表 - return sequencesUnlockDao.delete(condition); + return Boolean.TRUE.equals(transactionTemplate.execute(status -> { + try { + return sequencesUnlockDao.delete(condition); + } catch (Exception e) { + e.printStackTrace(); + status.setRollbackOnly(); + return false; + } + })); } @Override public synchronized boolean lock(Sequences sequences, boolean ignoreSeq) { if (!ignoreSeq) return lock(sequences); - if (sequences == null) + if (sequences == null || sequences.getWithOutSeq()) return true; SequencesUnlock condition = new SequencesUnlock(sequences); condition.setSeq(null); //将使用中表的对应数据删除,空闲表中数据在生成时会删除,因此这里不需要处理该表 - return sequencesUnlockDao.delete(condition); + return Boolean.TRUE.equals(transactionTemplate.execute(status -> { + try { + return sequencesUnlockDao.delete(condition); + } catch (Exception e) { + e.printStackTrace(); + status.setRollbackOnly(); + return false; + } + })); } @Override - public synchronized void release() { + public synchronized boolean release() { //列出所有使用中表存在的序号 List sequencesUnlockList = sequencesUnlockDao.listAll(); @@ -265,13 +317,23 @@ public class SequencesGenerator implements Generator { } //将使用中表的序号放到空闲表中 - sequencesUnusedDao.saveBatch(sequencesUnusedList); //删除所有使用中表的数据 - sequencesUnlockDao.deleteAll(); + return Boolean.TRUE.equals(transactionTemplate.execute(status -> { + try { + //将使用中表的序号放到空闲表中 + //删除所有使用中表的数据 + return sequencesUnusedDao.saveBatch(sequencesUnusedList) && + sequencesUnlockDao.deleteAll(); + } catch (Exception e) { + e.printStackTrace(); + status.setRollbackOnly(); + return false; + } + })); } @Override - public synchronized void release(Date begin, Date end) { + public synchronized boolean release(Date begin, Date end) { //列出指定时间段内使用中表存在的序号 List sequencesUnlockList = sequencesUnlockDao.listByDate(begin, end); @@ -281,9 +343,19 @@ public class SequencesGenerator implements Generator { } //将指定时间段内使用中表的序号放到空闲表中 - sequencesUnusedDao.saveBatch(sequencesUnusedList); //删除指定时间段内使用中表的数据 - sequencesUnlockDao.deleteByDate(begin, end); + return Boolean.TRUE.equals(transactionTemplate.execute(status -> { + try { + //将指定时间段内使用中表的序号放到空闲表中 + //删除指定时间段内使用中表的数据 + return sequencesUnusedDao.saveBatch(sequencesUnusedList) && + sequencesUnlockDao.deleteByDate(begin, end); + } catch (Exception e) { + e.printStackTrace(); + status.setRollbackOnly(); + return false; + } + })); } @Override @@ -297,37 +369,68 @@ public class SequencesGenerator implements Generator { } @Override - public synchronized void release(Sequences sequences) { + public synchronized boolean release(Sequences sequences) { if (sequences == null) - return; - sequencesUnlockDao.delete(new SequencesUnlock(sequences)); - sequencesUnusedDao.save(new SequencesUnused(sequences, new Date())); + return true; + return Boolean.TRUE.equals(transactionTemplate.execute(status -> { + try { + return sequencesUnlockDao.delete(new SequencesUnlock(sequences)) + && sequencesUnusedDao.save(new SequencesUnused(sequences, new Date())); + } catch (Exception e) { + e.printStackTrace(); + status.setRollbackOnly(); + return false; + } + })); } @Override - public synchronized void release(Sequences sequences, boolean ignoreSeq) { + public synchronized boolean release(Sequences sequences, boolean ignoreSeq) { if (!ignoreSeq) { - release(sequences); - return; + return release(sequences); } if (sequences == null) - return; - SequencesUnlock sequencesUnlock = new SequencesUnlock(sequences); - sequencesUnlock.setSeq(null); - sequencesUnlockDao.delete(sequencesUnlock); - //由于忽略了序号,因此不需要将未使用序号放到SequencesUnused里面 + return true; + return Boolean.TRUE.equals(transactionTemplate.execute(status -> { + try { + SequencesUnlock sequencesUnlock = new SequencesUnlock(sequences); + sequencesUnlock.setSeq(null); + //由于忽略了序号,因此不需要将未使用序号放到SequencesUnused里面 + return sequencesUnlockDao.delete(sequencesUnlock); + } catch (Exception e) { + e.printStackTrace(); + status.setRollbackOnly(); + return false; + } + })); } @Override - public synchronized void clear() { - sequencesUnlockDao.deleteAll(); - sequencesUnusedDao.deleteAll(); + public synchronized boolean clear() { + return Boolean.TRUE.equals(transactionTemplate.execute(status -> { + try { + return sequencesUnlockDao.deleteAll() && + sequencesUnusedDao.deleteAll(); + } catch (Exception e) { + e.printStackTrace(); + status.setRollbackOnly(); + return false; + } + })); } @Override - public synchronized void clear(Date begin, Date end) { - sequencesUnlockDao.deleteByDate(begin, end); - sequencesUnusedDao.deleteByDate(begin, end); + public synchronized boolean clear(Date begin, Date end) { + return Boolean.TRUE.equals(transactionTemplate.execute(status -> { + try { + return sequencesUnlockDao.deleteByDate(begin, end) && + sequencesUnusedDao.deleteByDate(begin, end); + } catch (Exception e) { + e.printStackTrace(); + status.setRollbackOnly(); + return false; + } + })); } @Override diff --git a/src/main/java/com/yanghuanglin/seq/po/Sequences.java b/src/main/java/com/yanghuanglin/seq/po/Sequences.java index 74c4466..bc73037 100644 --- a/src/main/java/com/yanghuanglin/seq/po/Sequences.java +++ b/src/main/java/com/yanghuanglin/seq/po/Sequences.java @@ -42,6 +42,11 @@ public class Sequences { */ private transient Integer day; + /** + * 临时字段,表示序号对象不包含序号 + */ + private transient Boolean withOutSeq; + public Sequences() { } @@ -114,6 +119,14 @@ public class Sequences { this.day = day; } + public Boolean getWithOutSeq() { + return withOutSeq; + } + + public void setWithOutSeq(Boolean withOutSeq) { + this.withOutSeq = withOutSeq; + } + /** * 将序号增加指定步长 * @@ -156,6 +169,7 @@ public class Sequences { ", year=" + year + ", month=" + month + ", day=" + day + + ", withOutSeq=" + withOutSeq + '}'; } } diff --git a/src/test/java/SeqTest.java b/src/test/java/SeqTest.java index 53b6efc..2f1b10d 100644 --- a/src/test/java/SeqTest.java +++ b/src/test/java/SeqTest.java @@ -1,10 +1,14 @@ import com.mysql.cj.jdbc.MysqlDataSource; +import com.yanghuanglin.seq.config.BaseConfig; import com.yanghuanglin.seq.config.GeneratorConfig; import com.yanghuanglin.seq.config.TableConfig; import com.yanghuanglin.seq.generator.Generator; import com.yanghuanglin.seq.generator.impl.SequencesGenerator; import com.yanghuanglin.seq.po.Sequences; import org.junit.Test; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.support.TransactionTemplate; import java.util.HashSet; import java.util.Set; @@ -26,12 +30,15 @@ public class SeqTest { dataSource.setPassword("root"); GeneratorConfig generatorConfig = new GeneratorConfig(dataSource); + TableConfig tableConfig = new TableConfig(); tableConfig.setTable("sequences"); tableConfig.setKeyColumn("SEQUENCE_KEY"); tableConfig.setTypeColumn("SEQUENCE_TYPE"); tableConfig.setSeqColumn("CURRENT"); generatorConfig.setTableConfig(tableConfig); + generatorConfig.setDayZeroFilling(false); + generatorConfig.setMonthZeroFilling(false); generator = new SequencesGenerator(generatorConfig); } @@ -44,12 +51,9 @@ public class SeqTest { Set set = new HashSet<>(); ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 10, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<>(100)); for (int i = 0; i < 5; i++) { - int finalI = i; threadPoolExecutor.execute(() -> { Sequences sequences = generator.generate("SNT", "MISSION"); String formattedSeq = generator.format(sequences.getSeq(), "处〔#year#〕10801#seq#"); -// if (finalI % 2 == 0) -// System.out.println(3 / 0); generator.lock(sequences); set.add(formattedSeq); System.out.println(formattedSeq);