最近项目蛮忙的也就没有上来看一下,在这个项目中用的是liferay5.0,也没遇到什么问题,觉得没什么
好写的了,只是为了加快项目进度试用了一下他提供的网站导入导出,导出没什么好说的,只是在导入
的过程中失败的概率很高,也许几十次可以成功一次,因为网站比较多十几个如果一个一个做太慢了,
导入失败报的原因基本上都一样,就是违返了主键约束,在liferay中所有的主键都是程序生成的,数据
库中有一个表名counter这就是主键表,
public long increment(String name, int size)
throws SystemException {
if (size < _MINIMUM_INCREMENT_SIZE) {
size = _MINIMUM_INCREMENT_SIZE;
}
CounterRegister register = getCounterRegister(name);
synchronized (register) {
long newValue = register.getCurrentValue() + size;
if (newValue > register.getRangeMax()) {
Session session = null;
try {
session = openSession();
Counter counter = (Counter)session.get(
Counter.class, register.getName(),
LockMode.UPGRADE);
newValue = counter.getCurrentId() + 1;
long rangeMax =
counter.getCurrentId() +
register.getRangeSize();
counter.setCurrentId(rangeMax);
session.save(counter);
session.flush();
register.setCurrentValue(newValue);
register.setRangeMax(rangeMax);
}
catch (Exception e) {
throw HibernateUtil.processException(e);
}
finally {
closeSession(session);
}
}
else {
register.setCurrentValue(newValue);
}
return newValue;
}
}
这是生成主键的代码,先读一次这个表,找到当前主键值,加上一个COUNTER_INCREMENT值,这个值默认
是100,然后修改表中的主键值,以后就不访问这个表了,每次把这个值加一,当超过
register.getRangeMax()值时再次重复这个动作,问题就是在这个地方了,当你的数据少时导入是不会
出错的,当数据很多时,我的一般一个社区会有1000-2000条数据,这样就会去读10次以前的数据库,一
次两次不会出错,多了就会出错,有时候在4,7次重复这个动作时,这个概率不是很稳定,只要有一次
他取的值是最原始的数据了,也就是第一次修改之前的,那么这个ID就发生了得重复了,当运气不好的
时候这个ID用到了同一个表中自然就出错了,Counter counter = (Counter)session.get
(Counter.class, register.getName(),LockMode.UPGRADE);这个总是先到缓存中去取,可是为什么会突
然取到很久以前的一个值就不得而知了,查不出来原因不代表我们不能解决,我们可以修改
COUNTER_INCREMENT值,把他放到足够在来减少访问counter这个动作的次数,在portal-ext.properties
中增加counter.increment=你认为足够大的值。OK,搞定。
好写的了,只是为了加快项目进度试用了一下他提供的网站导入导出,导出没什么好说的,只是在导入
的过程中失败的概率很高,也许几十次可以成功一次,因为网站比较多十几个如果一个一个做太慢了,
导入失败报的原因基本上都一样,就是违返了主键约束,在liferay中所有的主键都是程序生成的,数据
库中有一个表名counter这就是主键表,
public long increment(String name, int size)
throws SystemException {
if (size < _MINIMUM_INCREMENT_SIZE) {
size = _MINIMUM_INCREMENT_SIZE;
}
CounterRegister register = getCounterRegister(name);
synchronized (register) {
long newValue = register.getCurrentValue() + size;
if (newValue > register.getRangeMax()) {
Session session = null;
try {
session = openSession();
Counter counter = (Counter)session.get(
Counter.class, register.getName(),
LockMode.UPGRADE);
newValue = counter.getCurrentId() + 1;
long rangeMax =
counter.getCurrentId() +
register.getRangeSize();
counter.setCurrentId(rangeMax);
session.save(counter);
session.flush();
register.setCurrentValue(newValue);
register.setRangeMax(rangeMax);
}
catch (Exception e) {
throw HibernateUtil.processException(e);
}
finally {
closeSession(session);
}
}
else {
register.setCurrentValue(newValue);
}
return newValue;
}
}
这是生成主键的代码,先读一次这个表,找到当前主键值,加上一个COUNTER_INCREMENT值,这个值默认
是100,然后修改表中的主键值,以后就不访问这个表了,每次把这个值加一,当超过
register.getRangeMax()值时再次重复这个动作,问题就是在这个地方了,当你的数据少时导入是不会
出错的,当数据很多时,我的一般一个社区会有1000-2000条数据,这样就会去读10次以前的数据库,一
次两次不会出错,多了就会出错,有时候在4,7次重复这个动作时,这个概率不是很稳定,只要有一次
他取的值是最原始的数据了,也就是第一次修改之前的,那么这个ID就发生了得重复了,当运气不好的
时候这个ID用到了同一个表中自然就出错了,Counter counter = (Counter)session.get
(Counter.class, register.getName(),LockMode.UPGRADE);这个总是先到缓存中去取,可是为什么会突
然取到很久以前的一个值就不得而知了,查不出来原因不代表我们不能解决,我们可以修改
COUNTER_INCREMENT值,把他放到足够在来减少访问counter这个动作的次数,在portal-ext.properties
中增加counter.increment=你认为足够大的值。OK,搞定。