2009-12-07 30 views
6

Tôi đang chạy một ứng dụng với các thành phần sau:WS 6.1, JPA với JTA, Hibernate, Spring: hồi dữ liệu vấn đề

  • Oracle 9i
  • WS 6.1.0.23 với WS và EJB3 tính năng gói
  • JPA với Hibernate 3.3.2.GA là nhà cung cấp (với Hibernate-EntityManager 3.4.0) quản lý giao dịch
  • mùa xuân cho WS: UowTransactionManager (mùa xuân 2.5.6)
  • xuân webflow với kiên trì dòng chảy quản lý (2.0. 8), tức là quản lý thực thể được đăng trong phiên http và được khôi phục trên mỗi yêu cầu.

Trong mỗi yêu cầu đi từ bộ điều khiển web để các lớp dịch vụ (chú thích với @Transactional Spring), tôi đã nhận thấy rằng đối với mỗi truy vấn SQL mà Hibernate thực hiện trong việc gọi dịch vụ bên trong các giao dịch, một DataSource connnection mới là được yêu cầu từ jndi DataSource bởi ConnectionProvider của Hibernate, cho đến khi DataSource hết các kết nối miễn phí và cuối cùng bị treo.

Dưới đây là các bộ phận của cấu hình:

  1. mùa xuân:

    <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. Dịch vụ

    @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(...); 
        } 
    } 
    

Lưu ý giao dịch là chỉ đọc, đó là bình thường đối với dòng chảy bền bỉ: chỉ sự chuyển đổi cuối cùng (với cam kết = true) gọi một phương pháp giao dịch không chỉ đọc. Bật cờ readOnly sẽ tự động chuyển chế độ xả Hibernate sang MANUAL.

Trong khi làm một số debug, tôi nhận thấy như sau:

  • Người quản lý giao dịch UOW được gọi một cách chính xác trong chuỗi đánh chặn của dịch vụ, điều này gợi ý rằng một giao dịch đang hoạt động
  • Hibernate yêu cầu một kết nối bằng cách gọi DataSource.getConnection() trên DataSource thô được tiêm vào EMF; Chiến lược nhận kết nối là từ InjectedDataSourceConnectionProvider của Hibernate, và lớp này tham chiếu đến WAS DataSource (không phải là proxy nhận thức được một giao dịch đang hoạt động, hoặc như vậy).

Tôi đoán vấn đề ở điểm thứ hai này, nhưng tôi không thể tìm thấy lỗi trong cấu hình của mình. Ai có thể giúp được không?

Cảm ơn sự giúp đỡ của bạn.

Trả lời

2

một số dự đoán hoang dã từ cấu hình của chúng tôi

  • ngủ đông prop - hibernate.connection.release_mode = after_statement
  • web.xml ref tài nguyên nguồn dữ liệu cấu hình - < res-chia sẻ-phạm vi > có thể chia sẻ </res-chia sẻ -scope >
  • mùa xuân sessionfactory config - useTransactionAwareDataSource = "true"

nó thậm chí có thể là một vấn đề cấu hình bên trong là

+0

Thứ hai là câu trả lời đúng. Phạm vi chia sẻ của DataSource là Unsharable. Cảm ơn rất nhiều. – Gaetan

0

Tôi nghĩ (và hy vọng) rằng vấn đề của bạn bắt nguồn từ thực tế là bằng cách sử dụng thuộc tính dataSource, nó mặc định là "nonJtaDataSource".Cấu hình mặc định (đơn giản) thực sự được tối ưu hóa cho các hệ thống giao dịch cấp thấp hơn (tomcat/SE) và không phải là phần cứng nhiều hơn mà bạn đang sử dụng.

Bạn sẽ cần phải định cấu hình nhà máy quản lý tổ chức để có nguồn dữ liệu jta. Cách mà tôi đã làm điều này là tạo JtaPersistenceUnitPostProcessor của riêng tôi, nơi tôi có thể thiết lập điều này.

Bằng cách làm theo cách này tôi đã có thể đặt EMF để sử dụng một JtaDatasource, tôi không chắc chắn nếu có một cách tốt hơn để làm điều này. Bạn có thể đơn giản, như một POC thêm tham chiếu nguồn dữ liệu jta vào persistence.xml của bạn.

+0

Nhìn vào mã Spring cho DefaultPersistenceUnitManager và PersistenceUnitReader, tôi nhận thấy rằng DataSource được tiêm vào LocalContainerEntityManagerFactoryBean được sử dụng như là để xác định nguồn dữ liệu jta- và non-jta của đơn vị persistence (nếu một phần tử tương ứng được khai báo trong persistence.xml, với bất kỳ giá trị nào). Cuối cùng, nếu không có phần tử nguồn dữ liệu phi jta nào được chỉ định trong PU, cùng nguồn dữ liệu đó được tiêm dưới dạng nguồn dữ liệu không phải jta. Vì vậy, tôi đã thêm một phần tử nguồn dữ liệu jta vào persistence.xml của mình và nó vẫn hoạt động giống nhau. – Gaetan

+0

Spring cung cấp 3 triển khai cho giao diện ConnectionProvider của Hibernate: LocalDataSourceConnectionProvider và 2 lớp con, LocalJtaDataSourceConnectionProvider và TransactionAwareDataSourceConnectionProvider; tất cả chúng đều nằm trong gói orm.hibernate3 (không phải jpa), điều này tôi không nghĩ chúng nên được sử dụng cho JPA. Khi chạy ứng dụng của tôi, nhà cung cấp kết nối được cấu hình là InjectedDataSourceConnectionProvider của Hibernate; Tôi sẽ mong đợi một số loại DataSource giao dịch nhận biết (trừ khi giao dịch được giao hoàn toàn cho WAS DataSource) ... – Gaetan

Các vấn đề liên quan