我需要将一个大型 XML 文件(包含按 ID 排序的 600 万条记录)与 SAP MaxDB 数据库表同步。
这是我目前的策略:
- 从文件中读取 XML 对象并转换为 Java bean
- 从数据库加载具有相同主键的对象(见下文)
- 如果对象不存在,则插入对象
- 如果对象存在并被更改,则更新对象
- 在该过程结束时,扫描数据库表中未包含在文件中的(已删除)对象
出于效率原因,“加载数据库对象”方法保留下 1000 条记录的缓存并发出语句以加载下一组对象。它是这样工作的:
List<?> objects = (List<?>)transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
ht.setMaxResults(BUNCH_SIZE);
ht.setFetchSize(BUNCH_SIZE);
List<?> objects = ht.find("FROM " + simpleName + " WHERE " +
primaryKeyName + " >= ? ORDER BY " + primaryKeyName, primaryValue);
return objects;
}
});
不幸的是,对于 BUNCH_SIZE (10,000) 的一些常量值,我得到一个 SQL 异常“导致表空间耗尽”。
- 如何更好地优化流程?
- 如何避免 SQL 异常/束大小问题?
保存更改对象的代码如下:
if (prevObject == null) {
ht.execute(new HibernateCallback(){
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
session.save(saveObject);
session.flush();
session.evict(saveObject);
return null;
}
});
newObjects++;
} else {
List<String> changes = ObjectUtil.getChangedProperties(prevObject, currentObject);
if (hasImportantChanges(changes)) {
changedObjects++;
ht.merge(currentObject);
} else
unchangedObjects++;
}
}
虽然此代码原则上有效,但如果源文件中有很多新的或更改的对象,它会产生大量的数据库日志条目(我们谈论的是超过 50 GB 的日志备份)。
- 我可以通过使用较低的事务隔离级别来改进此代码吗?
- 我可以减少写入的数据库日志数据量吗?
- 可能是数据库配置有问题?
我非常感谢任何帮助。非常感谢,马蒂亚斯