Ich arbeite an einem latenzempfindlichen Teil einer Anwendung, im Grunde werde ich ein Netzwerkereignis erhalten, um die Daten zu transformieren und dann alle Daten in die DB einzufügen. Nach dem Profiling sehe ich, dass meine gesamte Zeit damit verbracht wird, die Daten zu speichern. hier ist der CodeHochleistungs-Hibernate-Insert
private void insertAllData(Collection<Data> dataItems)
{
long start_time = System.currentTimeMillis();
long save_time = 0;
long commit_time = 0;
Transaction tx = null;
try
{
Session s = HibernateSessionFactory.getSession();
s.setCacheMode(CacheMode.IGNORE);
s.setFlushMode(FlushMode.NEVER);
tx = s.beginTransaction();
for(Data data : dataItems)
{
s.saveOrUpdate(data);
}
save_time = System.currentTimeMillis();
tx.commit();
s.flush();
s.clear();
}
catch(HibernateException ex)
{
if(tx != null)
tx.rollback();
}
commit_time = System.currentTimeMillis();
System.out.println("Save: " + (save_time - start_time));
System.out.println("Commit: " + (commit_time - save_time));
System.out.println();
}
Die Größe der Sammlung immer kleiner als 20 ist hier die Zeitdaten, die ich sehe:
Save: 27
Commit: 9
Save: 27
Commit: 9
Save: 26
Commit: 9
Save: 36
Commit: 9
Save: 44
Commit: 0
Diese verwirrend für mich ist. Ich denke, dass die save
sollte schnell sein und die ganze Zeit sollte auf commit
ausgegeben werden. aber klar liege ich falsch. Ich habe auch versucht, die Transaktion zu entfernen (es ist nicht wirklich notwendig), aber ich sah schlechtere Zeiten ... Ich habe hibernate.jdbc.batch_size = 20 ...
Ich kann erwarten, dass so viele wie 500 Nachrichten/Sek also brauche ich die Verarbeitung einzelner Nachrichten unter 20 Millisekunden.
ich brauche diese Operation, um so schnell wie möglich zu sein, idealerweise würde es nur einen Hin- und Rückweg zur Datenbank geben. Wie kann ich das machen?
BTW, sollen Sie 'commit()' nach dem 'flush()' wenn 'FlushMode # NIEMALS' verwenden? –
@Pascal Thivent. Ich weiß nicht :-) – luke
Nun, lesen Sie das Javadoc von 'Transaction # commit()' :) –