大きな 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 を超えるログ バックアップについて話している)。
- 低いトランザクション分離レベルを使用して、このコードを改善できますか?
- 書き込まれるデータベース ログ データの量を減らすことはできますか?
- データベースの構成に問題があるのではないでしょうか?
どんな助けにもとても感謝しています。どうもありがとう、マティアス