Я запускаю приложение со следующими компонентами:
- Oracle 9i
- WAS 6.1.0.23 с пакетом функций WS и EJB3
- JPA с Hibernate 3.3.2.GA в качестве поставщика (с Hibernate-EntityManager 3.4.0)
- Менеджер транзакций Spring для WAS: UowTransactionManager (весна 2.5.6)
- Веб-поток Spring с управляемым потоком постоянством (2.0.8), т. Е. Менеджер сущностей сериализуется в сеанс http и восстанавливается при каждом запросе.
В каждом запросе, переходящем от веб-контроллера к уровню обслуживания (аннотированному с помощью SpringT @ Transactional), я заметил, что для каждого запроса SQL, который Hibernate выполняет во время вызова службы внутри транзакции, новое соединение DataSource запрашивается из JNDI DataSource от Hibernate ConnectionProvider, пока DataSource не исчерпает свободные соединения и в конечном итоге зависает.
Вот части конфигурации:
Spring:
<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>
Услуга
@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(...);
}
}
Обратите внимание, что транзакция доступна только для чтения, что является нормальным для постоянства потока: только последний переход (с commit = true) вызывает не транзакционный метод readOnly. Включение флага readOnly автоматически переводит режим сброса в спящий режим в РУЧНОЙ.
Во время отладки я заметил следующее:
- Менеджер транзакций UOW корректно вызывается в цепочке перехвата службы, что указывает на то, что транзакция активна
- Hibernate запрашивает соединение, вызывая DataSource.getConnection () для необработанного DataSource, который вводится в EMF; Стратегия получения соединения взята из InjectedDataSourceConnectionProvider в Hibernate, и этот класс ссылается на WAS DataSource (а не на прокси-сервер, который знает об активной транзакции или тому подобное).
Полагаю, проблема в этом втором пункте, но я не могу найти ошибку в моей конфигурации. Кто-нибудь может помочь?
Спасибо за вашу помощь.