hibernate - txt - sql server update por lotes




Uso de StatelessSession para el procesamiento por lotes (2)

De la documentación se enlaza a:

En particular, una sesión sin estado no implementa un caché de primer nivel ni interactúa con ningún caché de consulta o de segundo nivel. No implementa escritura por detrás transaccional o comprobación automática de errores. Las operaciones realizadas con una sesión sin estado nunca se conectan en cascada a las instancias asociadas. Las colecciones son ignoradas por una sesión sin estado. Las operaciones realizadas a través de una sesión sin estado omiten el modelo de eventos de Hibernate y los interceptores. Debido a la falta de un caché de primer nivel, las sesiones sin estado son vulnerables a los efectos de alias de datos.

¡Esas son algunas limitaciones significativas!

Si los objetos que está creando, o las modificaciones que está realizando, son cambios simples en los campos escalares de objetos individuales, entonces creo que una sesión sin estado no tendría desventajas en comparación con una sesión normal por lotes. Sin embargo, tan pronto como quiera hacer algo un poco más complejo: manipular una propiedad de colección de un objeto u otro objeto en cascada desde el primero, por ejemplo, la sesión sin estado es más un obstáculo que una ayuda.

Más generalmente, si la sesión ordinaria por lotes da un rendimiento que es lo suficientemente bueno, entonces la sesión sin estado es simplemente una complejidad innecesaria. Se parece vagamente a la sesión ordinaria, pero tiene una API diferente y una semántica diferente, que es el tipo de cosa que invita a los errores.

Ciertamente, puede haber casos en los que sea la herramienta adecuada, pero creo que estos son la excepción y no la regla.

De la documentation

Si tenemos un caso donde necesitamos insertar 1000 000 filas / objetos:

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

for ( int i=0; i<100000; i++ ) {
    Customer customer = new Customer(.....);
    session.save(customer);
    if ( i % 20 == 0 ) { //20, same as the JDBC batch size
        //flush a batch of inserts and release memory:
        session.flush();
        session.clear();
    }
}

tx.commit();
session.close();

¿Por qué deberíamos usar ese enfoque? Qué tipo de beneficio nos brinda en comparación con StatelessSession one:

    StatelessSession session = sessionFactory.openStatelessSession();
    Transaction tx = session.beginTransaction();

    for ( int i=0; i<100000; i++ ) {
      Customer customer = new Customer(.....);
      session.insert(customer);
    }    

    tx.commit();
    session.close();

Quiero decir, este último ejemplo ("alternativo") no usa memoria, no es necesario sincronizar, limpiar el caché, ¿entonces se supone que esta es la mejor práctica para casos como este? ¿Por qué usar el anterior entonces?


La sesión sin estado tiene una ventaja sobre la sesión en términos de rendimiento porque la sesión sin estado omitirá el compromiso de transacción para los métodos de sesión o de descarga de sesión utilizados en el objeto de sesión. Sin embargo, es importante tener en cuenta que el servicio / DAO NO debe tratar de realizar la manipulación de datos en la sesión, ya sea a los objetos principales o a cualquier objeto secundario. Va a lanzar la excepción. Además, asegúrese de cerrar la sesión explícitamente, de lo contrario, uno terminará con conexiones filtradas.

Para obtener más rendimiento con la sesión sin estado, si una está utilizando una transacción impulsada por Spring, marque la transacción Spring como de solo lectura y establezca la propagación requerida como NUNCA.

Pero una vez más, no intente esto donde uno tiene que manipular el modelo de objetos.

@Transactional(value="someTxnManager", readOnly=true, propagation=Propagation.NEVER)
    public List<T> get(...) {

        return daoSupport.get(...);
    }

en daoSupport

StatelessSession session = sessionFactory.openStatelessSession();
try{
// do all operations here
}
...
...
finally{
            session.close();
}






batch-processing