estoy ejecutando una aplicación con los siguientes componentes:fue de 6.1, JPA con JTA, Hibernate, Spring: problema de la recuperación de datos
- Oracle 9i
- ERA 6.1.0.23 con WS y EJB3 ofrece paquete
- JPA con Hibernate 3.3.2.GA como proveedor (con Hibernate-EntityManager 3.4.0) gestor de transacciones
- resorte por fue: UowTransactionManager (primavera 2.5.6) WebFlow
- del resorte con persistencia gestionada por flujo (2.0. 8), es decir, el El administrador de entidades se serializa en la sesión http y se restaura en cada solicitud.
En cada solicitud que va desde el controlador web para la capa de servicio (anotado con @Transactional de primavera), me he dado cuenta que por cada consulta SQL que Hibernate realiza durante la invocación del servicio dentro de la transacción, un nuevo connnection origen de datos es solicitado por jndi DataSource por el proveedor de conexión de Hibernate, hasta que el DataSource se quede sin conexiones gratuitas y finalmente se cuelgue.
Estas son partes de la configuración:
primavera:
<tx:annotation-driven /> <context:component-scan base-package="org.home.myapp" /> <jee:jndi-lookup id="dataSource" jndi-name="jdbc/DS" resource-ref="true"/> <bean id="transactionManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager"/> <bean id="EMF" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/> </property> </bean>
persistence.xml
<persistence-unit name="persistence" transaction-type="JTA"> <properties> <property name="hibernate.archive.autodetection" value="class"/> <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle9iDialect"/> <property name="hibernate.current_session_context_class" value="jta"/> <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/> <property name="hibernate.format_sql" value="true"/> <property name="hibernate.show_sql" value="true"/> <property name="hibernate.default_batch_fetch_size" value="20"/> <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup"/> </properties> </persistence-unit>
Servicio
@Transactional(readOnly=true) @Service public class MyServiceImpl implements MyService { @Autowired MyDao dao; public void getSomething() { dao.findSomething(); } }
DAO
@Repository public class MyDaoJap implements MyDao { @PersistenceContext EntityManager em; public void findSomething() { em.find(...); } }
Nota la transacción es de sólo lectura, que es normal para el flujo de persistencia: sólo la última transición (con cometer = true) invoca un método transaccional no readOnly. Al encender el indicador readOnly, el modo de lavado de Hibernate se convierte automáticamente en MANUAL.
mientras hace algo de depuración, me di cuenta de lo siguiente:
- El administrador de transacciones UOW se invoca correctamente en la cadena de intercepción del servicio, lo que sugiere que una transacción está activo
- Hibernate pide una conexión invocando DataSource.getConnection() en el DataSource sin procesar que se inyecta en el EMF; La estrategia para obtener una conexión es del InjectedDataSourceConnectionProvider de Hibernate, y esta clase hace referencia al WAS DataSource (no un proxy que tenga conocimiento de una transacción activa, o tal).
Supongo que el problema está en este segundo punto, pero no puedo encontrar un error en mi configuración. ¿Alguien puede ayudar?
Gracias por su ayuda.
La segunda es la respuesta correcta. El alcance compartido de DataSource era Unsharable. Muchas gracias. – Gaetan