思路:利用数据库的排他锁机制,来达到集群流水号生成的唯一性
流水号表:
表名:SYS_IDENTITY 解释:SYS_IDENTITY【流水号生成】
备注:流水号生成
SYS_IDENTITY(SYS_IDENTITY【流水号生成】) | ||||||||
是否主键 | 字段名 | 字段描述 | 数据类型 | 长度 | 可空 | 约束 | 缺省值 | 备注 |
是 | ID | 主键 | NUMBER(18) | 18 |
|
|
| 主键 |
| NAME | 名称 | VARCHAR2(50) | 50 | 是 |
|
| 名称 |
| ALIAS | 别名 | VARCHAR2(20) | 20 | 是 |
|
| 别名 |
| REGULATION | 规则 | VARCHAR2(100) | 100 | 是 |
|
| 规则 |
| GENEVERYDAY | 每天生成 | SMALLINT |
| 是 |
|
| 每天生成 |
| NOLENGTH | 流水号长度 | INTEGER |
| 是 |
|
| 流水号长度 |
| CURDATE | 当前日期 | VARCHAR2(10) | 10 | 是 |
|
|
|
| INITVALUE | 初始值 | INTEGER |
| 是 |
|
| 初始值 |
| CURVALUE | 当前值 | INTEGER |
| 是 |
|
| 当前值 |
| STEP | 步长 | SMALLINT |
| 是 |
|
| 步长 |
获取流水号方法:
/**
* 根据流程规则别名获取得下一个流水号。
* @param alias 流水号规则别名。
* @return
*/
public synchronized String nextId(String alias){
//这里的查询语句为 SELECT <include refid="columns"/> FROM SYS_IDENTITY
//WHERE alias=#{alias} FOR UPDATE
Identity identity=this.dao.getByAlias(alias);
if(BeanUtils.isEmpty(identity)) return "";
String rule=identity.getRule();
int step=identity.getStep();
int genEveryDay=identity.getGenEveryDay();
//
Integer curValue=identity.getCurValue();
if(curValue==null) curValue=identity.getInitValue();
//每天都生成
if(genEveryDay==1){
String curDate=getCurDate();
String oldDate=identity.getCurDate();
if(!curDate.equals(oldDate)){
identity.setCurDate(curDate);
curValue=identity.getInitValue();
}
else{
curValue=curValue + step;
}
}
else{
curValue=curValue + step;
}
identity.setCurValue(curValue);
dao.update(identity);
//获取流水号。
String rtn=getByRule(rule,identity.getNoLength(),curValue);
return rtn;
}