Transacción con spring durante un bucle
Hola amigos, he seguido algunos temas excelentes con respecto a transaciones con Spring del cual estoy muy agradecido. Les comento que actualmente me encuentro con un problema que les comento a continuación esperando su ayuda.
tengo el siguiente método configurado para utilizar transacciones de spring desde la capa de negocio.
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public void guardarProceso(List lista, Object objeto1,Object objeto2){
guardar(objeto1);
guardar(objeto2);
Kardex kardex = null;
for(Object entidad; lista){
kardex = find(entidad);
actualizar(kardex);
}
}
El problema es que al realizar el bucle for los dos objetos que se enviaron a guardar previamente y que están dentro de la transacción se hacen commit y se los puede ver en la base incluso antes de terminar el método (DEBUG). He realizado varias pruebas entre esas probar con otras entidades realizando la consulta y actualizando la entidad que me retorna dentro del for tratando de descartar que sea por el mapeo o por el tema de BDD y el problema persiste. Al inicio pensé que el problema era por la tabla, el mapeo, etc. Pero en realidad es cuando se realiza la acción descrita dentro de un bucle.
Ademas que si por algún motivo existiera un error dentro del bucle o posterior a este, como se realizo el commit esos datos se quedan inconsistente.
Investigando encontre que una solución para este problema es la de consultar previamente la lista y pasarla antes de iniciar la transacción. La probe y funciona pero para mi caso no es viable ya que el proceso en realidad es mucho mas complicado que el que les describo con fines de simplicidad.
Les agredezco mucho me pudieran ayudar con este tema...
- Inicie sesión o regístrese para enviar comentarios
Raro autocommit en transaction
Que raro porque se supone que en una transaccion no entraria el autocommit, quizas soluciones el problema donde defines el datasource, ahi debes indicar que no se realice el autocommit (
). Pero eso afectará inluso a las modificaciónes a DB que no sean transaccionales.
Será muy bueno conocer tu configuración de la transaccion y el codigo donde peristes, no vaya a ser que opr ahi estes forzando un commit manualmente.
autocommit
Gracias por tu respuesta...
La verdad es muy raro y como explico pasa siempre que realizo una consulta a partir de una lista y al cambiar algún valor de lo recuperado me hace commit del resto del método..... ayer me di cuenta incluso si no le envio a actualizar igual me realiza el commit es decir, si hago esto:
Kardex kardex = null;
for(Object entidad; lista){
kardex = find(entidad);
kardex.setCantidad(10); al realizar este cambio me realiza el commit..
//actualizar(kardex);
}
Mi configuración es esta:
y el metodo donde aplico la tx es:
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.DEFAULT)
public void guardarAvisoIngresoManual(BdgAvisoIngreso bdgAvisoIngreso, List listaAvisoIngresoDetalle) {
try {
CpsOrdenCompraDetalle detalleOC = null;
CpsItem item = null;
for (BdgAvisoIngresoDetalle detalleAviso : listaAvisoIngresoDetalle) {
item = nItems.getItem(detalleAviso.getCpsItem().getItmId()); // Es el mismo caso pero si no actualizo ningun valor no pasa nada.
detalleOC = nOrdenCompra.generarDetalleOrdenCompra(detalleAviso, ordenCompra, item);
listaDetalleOC.add(detalleOC);
}
nOrdenCompra.guardarOrdenCompra(ordenCompra); // Al entrar al bucle siguiente realiza el autocommit...
// Aqui suprimo código por que en realidad con eso o sin eso igual tengo el mismo problema en este punto
//Hay que tomar en cuenta que por ejemplo en el bucle de arriba hago algo parecido la diferencia es que el objeto que recupero no lo modifico, solo
//utilizo la información que recupero.
Bdg_kardex kardex = null;
for(BdgAvisoIngresoDetalle detalleAviso : listaAvisoIngresoDetalle){
kardex = nKardex.buscar(detalleAviso .idItem, detalleAviso .idLugar, detalleAviso .idmovimiento);
kardex.setCantidad(10); al realizar este cambio me realiza el commit..
//actualizar(kardex);
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Error al grabar el aviso de ingreso.");
}
}
//El método en la persistencia para la busqueda del kardex es este:
public BdgKardex buscar(long idItem, long idLugar, Long idmovimiento) throws ERPPersistenciaExcepcion {
Session sesion = getSession();
try {
Criteria c = sesion.createCriteria(BdgKardex.class);
c.add(Restrictions.eq("cpsItem.itmId", idItem));
c.add(Restrictions.eq("corLugar.lugId", idLugar));
c.add(Restrictions.eq("corMovimiento.movId", idmovimiento));
return (BdgKardex) c.uniqueResult();
} catch (Exception e) {
throw new ERPPersistenciaExcepcion(e.getMessage());
} finally {
releaseSession(sesion);
}
}
Para complementar, probé con el primer lazo, recupendo el item y modificandolo e igual pasa lo mismo.... Como comente, si recupero la lista previo al método con la tx ahi si funciona...
De antemano te agredezco..
Se necesita que proporciones
Se necesita que proporciones mas informacion, como defines el objeto transaccion, como defines el datasource, como defines los objetos de servicio, etc.