2

我需要将一个大型 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 的日志备份)。

  • 我可以通过使用较低的事务隔离级别来改进此代码吗?
  • 我可以减少写入的数据库日志数据量吗?
  • 可能是数据库配置有问题?

我非常感谢任何帮助。非常感谢,马蒂亚斯

4

0 回答 0