Estoy trabajando en una parte sensible a la latencia de una aplicación, básicamente recibiré un evento de red para transformar los datos y luego insertar todos los datos en la base de datos. Después del perfilado, veo que básicamente todo mi tiempo lo paso intentando guardar los datos. aquí está el códigoinserto de hibernación de alto rendimiento
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();
}
El tamaño de la colección es siempre inferior a 20. Aquí está la información de temporización que veo:
Save: 27
Commit: 9
Save: 27
Commit: 9
Save: 26
Commit: 9
Save: 36
Commit: 9
Save: 44
Commit: 0
Esto es confuso para mí. Me imagino que el save
debe ser rápido y todo el tiempo se debe gastar en commit
. pero claramente estoy equivocado. También intenté eliminar la transacción (no es realmente necesario) pero vi tiempos peores ... He configurado hibernate.jdbc.batch_size = 20 ...
Puedo esperar obtener hasta 500 mensajes/seg entonces necesito que el manejo de un solo mensaje sea de menos de 20 milisegundos.
necesito que esta operación sea lo más rápida posible, idealmente solo habría una ida y vuelta a la base de datos. ¿Cómo puedo hacer esto?
BTW, ¿no se supone que 'commit() 'después de' flush() 'cuando se usa' FlushMode # NEVER'? –
@Pascal Thivent. No sé :-) – luke
Bien, lea el javadoc de 'Transaction # commit()' :) –