预定式存储:
为了保证在任何情况下键值都不会出现重复,应当使用预定式键值存储办法。在请求一个键值时,首先将数据库中的键值更新为下一个可用值,
然后将旧值提供给客户端。这样万一出现运行中断的话,最多就是这个键值被浪费掉。
记录式存储:
键值首先被返还给客户端,然后记录到数据库中。这样做的缺点是,一旦系统中断,就有可能出现客户端已经使用了一个键值,而这个键值却
没有来得及存储到数据库中的情况。在系统重启后,系统还会从这个已经被使用过的键值开始,从而导致错误。
单例模式应用:序列键管理器
为了保证在任何情况下键值都不会出现重复,应当使用预定式键值存储办法。在请求一个键值时,首先将数据库中的键值更新为下一个可用值,
然后将旧值提供给客户端。这样万一出现运行中断的话,最多就是这个键值被浪费掉。
记录式存储:
键值首先被返还给客户端,然后记录到数据库中。这样做的缺点是,一旦系统中断,就有可能出现客户端已经使用了一个键值,而这个键值却
没有来得及存储到数据库中的情况。在系统重启后,系统还会从这个已经被使用过的键值开始,从而导致错误。
单例模式应用:序列键管理器
方案一:没有数据库的情况
//序列键生成器(单例类)
public class KeyGenerator{
private static KeyGenerator keygen = new KeyGenerator();
private int key = 1000;
private KeyGenerator(){}
//静态工厂方法,提供自己的实例
public static KeyGenerator getInstance(){
return keygen;
}
//取值方法,提供一个合适的键值
public synchronized int getNextKey(){
return key ++;
}
}
//客户端
public class Client{
private static KeyGenerator keygen;
public static void main(String args[]){
keygen = KeyGenerator.getInstance();
System.out.println("Key = " + keygen.getNextKey());
System.out.println("Key = " + keygen.getNextKey());
System.out.println("Key = " + keygen.getNextKey());
}
}
//当系统重启时,计数就要重新开始
方案二:有数据库的情况:
//序列键生成器(单例类)
public class KeyGenerator{
private static KeyGenerator keygen = new KeyGenerator();
private int key = 1000;
private KeyGenerator(){}
//静态工厂方法,提供自己的实例
public static KeyGenerator getInstance(){
return keygen;
}
//取值方法,提供一个合适的键值
public synchronized int getNextKey(){
return getNextKeyFromDB();
}
private int getNextKeyFromDB(){
String sql1 = "UPDATE KeyTable SET keyValue = keyValue + 1";
String sql2 = "SELECT keyValue FROM KeyTable";
//execute the update SQL
//run the select query
//示意性的返还一个数值
return 1000;
}
}
//每次都向数据库查询键值,将这个键值登记到表里,然后将查询结果返还给客户端
方案三:键值的缓存方案
//序列键生成器(单例类)
public class KeyGenerator{
private static KeyGenerator keygen = new KeyGenerator();
private static final int POOL_SIZE = 20; //用于缓存20条记录
private KeyInfo key;
private KeyGenerator(){
key = new KeyInfo(POOL_SIZE);
}
//静态工厂方法,提供自己的实例
public static KeyGenerator getInstance(){
return keygen;
}
//取值方法,提供一个合适的键值
public synchronized int getNextKey(){
return key.getNextKey();
}
}
//KeyInfo类
public class KeyInfo{
private int keyMax;
private int keyMin;
private int nextKey;
private int poolSize;
public KeyInfo(int poolSize){
this.poolSize = poolSize;
retrieveFromDB(); //retrieve(检索)
}
//取值方法,提供键的最大值
public int getKeyMax(){
return keyMax;
}
public int getKeyMin(){
return keyMin;
}
//取值方法,提供键的当前值
public int getNextKey(){
if(nextKey > keyMax){
retrieveFromDB();
}
return nextKey ++;
}
//内部方法,从数据库提取键的当前值
private void retrieveFromDB(){
String sql1 = "UPDATE KeyTable SET keyValue = keyValue +" + poolSize +
"WHERE keyName = 'PO_NUMBER'";
String sql2 = "SELECT keyValue FROM KeyTable WHERE keyName = 'PO_NUMBER'";
//execute the above queries in a transaction and commit it //commit提交/委托
//assume the value returned is 1000 //assume假设
int keyFromDB = 1000;
keyMax = keyFromDB;
keyMin = keyFromDB - poolSize + 1;
nextKey = keyMin;
}
}
//客户端
public class Client{
private static KeyGenerator keygen;
public static void main(String args[]){
keygen = KeyGenerator.getInstance();
for(int i = 0; i < 20; i ++){
System.out.println("Key(" + (i+1) + ")=" + keygen.getNextKey());
}
}
}
方案四:有缓存的多序列键生成器
//KeyGenerator
import java.util.HashMap;
public class KeyGenerator{
private static KeyGenerator keygen = new KeyGenerator();
private static final int POOL_SIZE = 20;
private HashMap keyList = new HashMap(10);
private KeyGenerator(){
}
public static KeyGenerator getInstance(){
return keygen;
}
public synchronized int getNextKey(String keyName){
KeyInfo keyInfo;
if(keyList.containsKey(keyName)){
keyInfo = (KeyInfo)keyList.get(keyName);
System.out.println("Key found");
}else{
keyInfo = new KeyInfo(POOL_SIZE,keyName);
keyList.put(keyName,keyInfo);
System.out.println("New key created");
}
return keyInfo.getNextKey(keyName);
}
}
//KeyInfo类
public class KeyInfo{
private int keyMax;
private int keyMin;
private int nextKey;
private int poolSize;
private String keyName;
public KeyInfo(int poolSize,String keyName){
this.poolSize = poolSize;
this.keyName = keyName;
retrieveFromDB(); //retrieve(检索)
}
//取值方法,提供键的最大值
public int getKeyMax(){
return keyMax;
}
public int getKeyMin(){
return keyMin;
}
//取值方法,提供键的当前值
public int getNextKey(){
if(nextKey > keyMax){
retrieveFromDB();
}
return nextKey ++;
}
//内部方法,从数据库提取键的当前值
private void retrieveFromDB(){
String sql1 = "UPDATE KeyTable SET keyValue = keyValue +" + poolSize +
"WHERE keyName = " + keyName + "";
String sql2 = "SELECT keyValue FROM KeyTable WHERE keyName = " + keyNAme + "";
//execute the above queries in a transaction and commit it //commit提交/委托
//assume the value returned is 1000 //assume假设
int keyFromDB = 1000;
keyMax = keyFromDB;
keyMin = keyFromDB - poolSize + 1;
nextKey = keyMin;
}
}
//客户端
public class Client{
private static KeyGenerator keygen;
public static void main(String args[]){
keygen = KeyGenerator.getInstance();
for(int i = 0; i < 20; i ++){
System.out.println("Key(" + (i+1) + ")=" + keygen.getNextKey("PO_NUMBER"));
}
}
}273P
方案五:多例模式
//KeyGennerator
import java.util.HashMap;
public class KeyGenerator{
private static HashMap Kengens = new HashMap(10);
private static final int POOL_SIZE = 20;
private KeyInfo keyinfo;
private KeyGenerator(){}
private KeyGenerator(String keyName){
keyinfo = new KeyInfo(POOL_SIZE,keyName);
}
public static synchronized KeyGenerator getInstance(String keyName){
KeyGenerator keygen;
if(kengens.containsKey(keyName)){
keygen = (KeyGenerator)kengens.get(keyName);
}else{
keygen = new KeyGenerator(keyName);
}
return keygen;
}
public synchronized int getNextKey(){
return keyinfo.getNextKey();
}
//KeyInfo类与方案四里的相同
}
//客户端
public class Client{
private static KeyGenerator keygen;
public static void main(String args[]){
keygen = KeyGenerator.getInstance("PO_NUMBER");
for(int i = 0; i < 20; i ++){
System.out.println("Key(" + (i+1) + ")=" + keygen.getNextKey());
}
}
}