次のコンポーネントを含むアプリケーションを実行しています。
- オラクル9i
- WAS 6.1.0.23 と WS および EJB3 機能パック
- プロバイダーとして Hibernate 3.3.2.GA を使用する JPA (Hibernate-EntityManager 3.4.0 を使用)
- WAS の Spring トランザクション マネージャー: UowTransactionManager (Spring 2.5.6)
- フロー管理の永続性 (2.0.8) を備えた Spring Webflow。つまり、エンティティ マネージャーは http セッションにシリアル化され、要求ごとに復元されます。
Web コントローラーからサービス層 (Spring の @Transactional でアノテーションが付けられている) に送られる各要求で、Hibernate がトランザクション内でのサービス呼び出し中に実行する SQL クエリごとに、jndi DataSource から新しい DataSource 接続が要求されることに気付きました。 DataSource が空き接続を使い果たし、最終的にハングするまで、Hibernate の ConnectionProvider。
構成の一部を次に示します。
春:
<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(); } }
ダオ
@Repository public class MyDaoJap implements MyDao { @PersistenceContext EntityManager em; public void findSomething() { em.find(...); } }
トランザクションは読み取り専用であることに注意してください。これは、フロー永続性では正常です。最後の遷移 (commit=true を使用) のみが、非読み取り専用のトランザクション メソッドを呼び出します。readOnly フラグをオンにすると、自動的に Hibernate フラッシュ モードが MANUAL に変わります。
デバッグを行っているときに、次のことに気付きました。
- UOW トランザクション マネージャーは、サービスのインターセプト チェーンで正しく呼び出されます。これは、トランザクションがアクティブであることを示しています。
- Hibernate は、EMF に注入された生の DataSource で DataSource.getConnection() を呼び出して接続を要求します。接続を取得するための戦略は、Hibernate の InjectedDataSourceConnectionProvider からのものであり、このクラスは (アクティブなトランザクションなどを認識しているプロキシではなく) WAS DataSource を参照します。
問題はこの 2 番目のポイントにあると思いますが、構成にエラーが見つかりません。誰でも助けることができますか?
ご協力いただきありがとうございます。