6

次のコンポーネントを含むアプリケーションを実行しています。

  • オラクル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。

構成の一部を次に示します。

  1. 春:

    <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>
    
  2. 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>
    
  3. サービス

    @Transactional(readOnly=true) @Service
    public class MyServiceImpl implements MyService {
      @Autowired MyDao dao;
      public void getSomething() {
        dao.findSomething();
      }
    }
    
  4. ダオ

    @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 番目のポイントにあると思いますが、構成にエラーが見つかりません。誰でも助けることができますか?

ご協力いただきありがとうございます。

4

2 に答える 2

2

私たちの設定からのいくつかのワイルドな推測

  • hibernate prop - hibernate.connection.release_mode=after_statement
  • web.xml リソース ref データソース構成 - <res-sharing-scope>Shareable</res-sharing-scope>
  • spring sessionFactory 構成 - useTransactionAwareDataSource="true"

内部の構成の問題である可能性さえありました

于 2010-07-13T10:19:45.237 に答える
0

あなたの問題は、 dataSource プロパティを使用するとデフォルトで「nonJtaDataSource」になるという事実に起因すると思います(そして願っています)。デフォルトの (単純な) 構成は、低グレードのトランザクション システム (Tomcat/SE) 向けに最適化されており、使用しているハードコア スタック向けには最適化されていません。

jta データソースを持つようにエンティティ マネージャー ファクトリを構成する必要があります。私がこれを行った方法は、これを設定できる独自の JtaPersistenceUnitPostProcessor を作成することです。

このようにすることで、EMF が JtaDatasource を使用するように設定できましたが、これを行うためのより良い方法があるかどうかはわかりません。簡単に、POC として jta データソース参照を persistence.xml に追加できます。

于 2009-12-08T10:01:38.493 に答える