Descripción
Hemos encontrado al menos una situación en que una transacción manejada por el contenedor JBoss no es correctamente terminada con rollback o con commmit. Este caso se dio bajo el siguiente escenario:
- Utilizando Hibernate bajo CMT, es decir, JBoss hace el commit o el rollback de los EJB automáticamente. El caso del rollback se activa cuando se produce una excepción en la llamada.
- La consulta realizada es muy larga.
El comportamiento extraño se nota al ver en el log de JBoss efectivamente aparecen los UPDATE o INSERT ejecutados por Hibernate, pero al revisar la base de datos no se ven siempre los cambios. Resulta difícil determinar una correlación para definir cuando los cambios se harán bien o no.
Causa
Según la documentación de JBoss existe un bug histórico consistente en que cuando se produce un timeout de una transacción, ésta sólo se marca para rollback, pero éste no se realiza efectivamente. Esto incide en que los cambios quedan bloqueados y los locks que hayan sido tomados no son liberados.
Solución
Lamentablemente la solución que se indica consiste únicamente en no hacer operaciones muy largas dentro de una transacción. Aparentemente, al menos para JBoss 4.0.5 no existe una solución directa.
Alternativamente es posible aumentar el tiempo máximo para la transacción, lo que puede ser modificado en la propiedad del MBean org.jboss.tm.TransactionManagerService (en el caso por defecto) llamada TransactionTimeout. Más detalles sobre esto en el artículo Cómo cambiar el tiempo de timeout de transacciones en JBoss