2008-09-16 38 views
11

Tôi có một tệp tin applicationContext.xml và có hai org.springframework.orm.jpa.JpaTransactionManager (mỗi đơn vị lưu giữ riêng của mình, các cơ sở dữ liệu khác nhau) được cấu hình trong ứng dụng tùy chỉnh phần mềm trung gian Spring.

Tôi muốn sử dụng các giao dịch dựa trên chú thích (@Transactional), để không gây rối xung quanh với TransactionStatus cam kết, lưu và khôi phục.

Một đồng nghiệp nói rằng một cái gì đó bị nhầm lẫn làm điều này khi có nhiều nhà quản lý giao dịch, mặc dù các tập tin bối cảnh được thiết lập cấu hình một cách chính xác (tài liệu tham khảo đi đến các đơn vị kiên trì đúng. Bất cứ ai từng nhìn thấy một vấn đề?JPA Nhiều nhà quản lý giao dịch


Trong cấu hình của bạn, bạn sẽ có hai nhà quản lý giao dịch? bạn có phải txManager1 và txManager2?

đó là những gì tôi có với JPA, hai đậu mùa xuân khác nhau mà các nhà quản lý giao dịch.

Trả lời

9

Tôi đoán bạn có 2 lựa chọn

Nếu trường hợp sử dụng của bạn không bao giờ yêu cầu cập nhật cho cả hai cơ sở dữ liệu trong cùng một giao dịch, thì bạn có thể sử dụng hai JpaTransactionManagers, nhưng tôi không chắc chắn bạn sẽ có thể sử dụng phương pháp @Transactional ? Trong trường hợp này, bạn sẽ cần phải dự phòng về cơ chế cũ của việc sử dụng một cách đơn giản TransactionProxyFactoryBean để xác định ranh giới giao dịch, ví dụ:

<bean id="firstRealService" class="com.acme.FirstServiceImpl"/> 
<bean id="firstService" 
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 
    <property name="transactionManager" ref="firstJpaTm"/> 
    <property name="target" ref="firstRealService"/> 
    <property name="transactionAttributes"> 
     <props> 
      <prop key="insert*">PROPAGATION_REQUIRED</prop> 
      <prop key="update*">PROPAGATION_REQUIRED</prop> 
      <prop key="*">PROPAGATION_REQUIRED,readOnly</prop> 
     </props> 
    </property> 
</bean> 
<!-- similar for your second service --> 

Nếu bạn yêu cầu một giao dịch kéo dài cả hai cơ sở dữ liệu, sau đó bạn sẽ cần phải sử dụng một JTA quản lý giao dịch. Các trạng thái API:

Trình quản lý giao dịch này phù hợp cho các ứng dụng sử dụng JPA EntityManagerFactory duy nhất để truy cập dữ liệu giao dịch. JTA (thường thông qua JtaTransactionManager) là cần thiết để truy cập nhiều tài nguyên giao dịch trong cùng một giao dịch. Lưu ý rằng bạn cần định cấu hình nhà cung cấp JPA của bạn để phù hợp để làm cho nó tham gia vào các giao dịch JTA.

Điều này có nghĩa là bạn sẽ cần cung cấp cho người quản lý giao dịch JTA. Trong ứng dụng của chúng tôi, chúng tôi sử dụng cấu hình tương tự như sau:

<tx:annotation-driven transaction-manager="txManager"/> 

<bean id="txManager" 
    class="org.springframework.transaction.jta.JtaTransactionManager"> 
    <property name="transactionManagerName" value="appserver/jndi/path" /> 
</bean> 

Nếu bạn đang triển khai trong vòng một appserver, sau đó vào mùa xuân JtaTransactionManager cần phải làm một tra cứu cho người quản lý giao dịch thực XA-compliant JTA cung cấp bởi appserver. Tuy nhiên, bạn cũng có thể sử dụng trình quản lý giao dịch JTA độc lập (nhưng tôi chưa tự mình thử)

Để định cấu hình nhà cung cấp dịch vụ lưu giữ Jpa, tôi không quen thuộc. Bạn đang sử dụng nhà cung cấp kiên trì JPA nào?

Đoạn mã trên được dựa trên cách tiếp cận của chúng tôi, nơi chúng tôi đã sử dụng Hibernate nguyên bản thay vì thực thi JPA Hibernate. Trong trường hợp này, chúng ta có thể loại bỏ hai bean HibernateTransactionManager, và đơn giản là đảm bảo rằng cả hai SessionFactories đều được tiêm cùng một JTA TM, và sau đó sử dụng phần tử tx: annotation-driven.

Hy vọng điều này sẽ giúp

+0

u có thể cung cấp mã mẫu hoặc POC của jtaTransaction với nhiều cơ sở dữ liệu không? – dhroove

+0

[Spring JTA nhiều giao dịch tài nguyên trong Tomcat với ví dụ Atomikos] (http://www.javacodegeeks.com/2013/07/spring-jta-multiple-resource-transactions-in-tomcat-with-atomikos-example.html) – anasanjaria

3

Tình huống duy nhất mà bạn có thể có hai người quản lý giao dịch mùa xuân là nếu bạn không bao giờ có cả hai giao dịch mở cùng một lúc.Đây không phải là bản chất để làm với các giao dịch phân tán - các hạn chế tương tự được áp dụng ngay cả khi bạn muốn hai nguồn dữ liệu hoàn toàn tách biệt (nhưng có khả năng chồng chéo trong thời gian) giao dịch.

Các trình quản lý giao dịch của Spring đều sử dụng TransactionSynchronizationManager của Spring, giữ trạng thái quan trọng trong các biến ThreadLocal tĩnh, vì vậy các trình quản lý giao dịch được bảo đảm stomp trên trạng thái của nhau.

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