Hibernate-Sitzung mitten in einer großen Transaktion sicher beenden

Ich verwende Spring + Hibernate für einen Vorgang, bei dem buchstäblich Hunderttausende von Elementen erstellt und aktualisiert werden müssen. Etwas wie das

{
   ...
   Foo foo = fooDAO.get(...);
   for (int i=0; i<500000; i++) {
      Bar bar = barDAO.load(i);
      if (bar.needsModification() && foo.foo()) {
         bar.setWhatever("new whatever");
         barDAO.update(bar);
         // commit here
         Baz baz = new Baz();
         bazDAO.create(baz);
         // if (i % 100 == 0), clear
      }
   }
}

Um mich vor dem Verlust von Änderungen in der Mitte zu schützen, übernehme ich die Änderungen sofort nachbarDAO.update(bar):

HibernateTransactionManager transactionManager = ...; // injected by Spring
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus transactionStatus = transactionManager.getTransaction(def);
transactionManager.commit(transactionStatus);

n dieser Stelle muss ich sagen, dass der gesamte Prozess in einer Transaktion ausgeführt wird, die in @ eingebunden isorg.springframework.orm.hibernate3.support.ExtendedOpenSessionInViewFilter (ja, das ist eine Webapp).

Dies alles funktioniert mit einer Ausnahme: Nach einigen Tausend Aktualisierungen / Festschreibungen wird der gesamte Prozess sehr langsam, was höchstwahrscheinlich darauf zurückzuführen ist, dass der Speicher durch immer mehr Objekte in Spring / Hibernate aufgebläht wird.

n einer Nur-Ruhezustand-Umgebung kann dies leicht gelöst werden, indem Sie @ aufrufeorg.hibernate.Session#clear().

Nun, die Fragen:

Wann ist es eine gute Zeit fürclear()? Hat es große Leistungskosten?Warum sind keine Objekte wiebar oderbaz freigegeben / GCd automatisch? Was nützt es, sie nach dem Festschreiben in der Sitzung zu belassen (in der nächsten Iterationsschleife sind sie sowieso nicht erreichbar)? Ich habe noch keinen Speicherauszug erstellt, um dies zu beweisen, aber ich habe das gute Gefühl, dass sie immer noch da sind, bis sie vollständig beendet sind. Wenn die Antwort auf diese Frage "Cache im Ruhezustand" lautet, warum wird der Cache dann nicht geleert, wenn der verfügbare Speicher fast voll ist?ist es sicher / empfohlen @ anzuruforg.hibernate.Session#clear() direkt (unter Berücksichtigung des gesamten Frühlingskontexts, Dinge wie verzögertes Laden usw.)? Gibt es brauchbare Federwickler / Gegenstücke, um dasselbe zu erreichen?Wenn die Antwort auf die obige Frage zutrifft, was passiert mit objectfoo, angenommenclear() heißt in der Schleife? Was wäre wennfoo.foo() ist eine Lazy-Load-Methode?

Vielen Dank für die Antworten.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage