Pergunta

Estou executando um aplicativo com os seguintes componentes:

  • Oracle 9i
  • Foi 6.1.0.23 com pacote de recursos ws e ejb3
  • JPA com Hibernate 3.3.2.Ga como provedor (com Hibernate-IntityManager 3.4.0)
  • Spring Transaction Manager for: UowtransactionManager (Spring 2.5.6)
  • Spring Webflow com persistência gerenciada por fluxo (2.0.8), ou seja, o gerente de entidade é serializado na sessão HTTP e restaurado em cada solicitação.

Em cada solicitação que vai do controlador da web para a camada de serviço (anotada com o @Transactional de Spring), notei que, para cada consulta SQL que o Hibernate realiza durante a invocação de serviço dentro da transação, uma nova conexão com dados de dados é solicitada ao conjunto de dados JNDI por meio O ConnectionProvider da Hibernate, até que a fonte de dados fique sem conexões gratuitas e eventualmente pendure.

Aqui estão partes da configuração:

  1. 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>
    
  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. Serviço

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

    @Repository
    public class MyDaoJap implements MyDao {
      @PersistenceContext EntityManager em;
      public void findSomething() {
        em.find(...);
      }
    }
    

Nota A transação é somente leitura, o que é normal para a persistência de fluxo: apenas a última transição (com commit = true) chama um método transacional não readonamente. Ligar o sinalizador readonly gira automaticamente o modo de descarga de hibernação para manual.

Enquanto fazia alguma depuração, notei o seguinte:

  • O gerente de transação da UOW é invocado corretamente na cadeia de interceptação do serviço, o que sugere que uma transação está ativa
  • O Hibernate solicita uma conexão invocando DataSource.getConnection () na fonte de dados bruta que é injetada no EMF; A estratégia para obter uma conexão é do injeção de hibernateDataSourceConnectionProvider, e essa classe faz referência ao DataSource (não é um proxy que está ciente de uma transação ativa ou tal).

Acho que o problema está neste segundo ponto, mas não consigo encontrar um erro na minha configuração. Alguém pode ajudar?

Obrigado pela ajuda.

Foi útil?

Solução

Algumas suposições selvagens da nossa configuração

  • hibernate prop - hibernate.connection.release_mode = pós -estatamento
  • Web.xml Recurso Ref DataSource Config -u003Cres-sharing-scope> Compartilhávelu003C/res-sharing-scope>
  • Spring SessionFactory Config - USETransactionAwaredataSource = "true"

até pode ser uma questão de configuração dentro de

Outras dicas

Penso (e espero) que seus problemas decorrem do fato de que, ao usar a propriedade DataSource, isso é padronizado para uma "não jtadataSource". A configuração padrão (simples) é realmente otimizada para sistemas transacionais de menor grau (Tomcat/SE) e não a pilha mais hardcore que você está usando.

Você precisará configurar a fábrica do Entity Manager para ter um conjunto de dados JTA. A maneira como fiz isso é criar meu próprio jTaperSistenceUnitPostProcessor, onde eu poderia configurar isso.

Ao fazê -lo dessa maneira, pude definir a EMF para usar uma JTadataSource, não tenho certeza se existe uma maneira melhor de fazer isso. Você pode simplesmente, como um POC adicionar a referência de DataSource do JTA à sua persistência.xml.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top