6

我正在运行一个包含以下组件的应用程序:

  • 甲骨文 9i
  • 带有 WS 和 EJB3 功能包的 WAS 6.1.0.23
  • 使用 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 连接Hibernate 的 ConnectionProvider,直到 DataSource 用完空闲连接并最终挂起。

以下是部分配置:

  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. 持久性.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 数据源(不是知道活动事务的代理等)。

我想问题出在第二点,但我在配置中找不到错误。有人可以帮忙吗?

谢谢你的帮助。

4

2 回答 2

2

我们的配置中的一些疯狂猜测

  • 休眠道具 - hibernate.connection.release_mode=after_statement
  • web.xml 资源参考数据源配置 - <res-sharing-scope>可共享</res-sharing-scope>
  • 春季 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 回答