2012-03-07 28 views
6

Tôi đang sử dụng JAX-RS để cung cấp giao diện dựa trên HTTP để quản lý mô hình dữ liệu. Mô hình dữ liệu được lưu trữ trong một cơ sở dữ liệu và tương tác với thông qua JPA.Cách quản lý giao dịch với JAX-RS, Spring và JPA

Điều này cho phép tôi sửa đổi giao diện cho mô hình dữ liệu cho phù hợp với các máy khách REST và hầu như có vẻ hoạt động khá tốt. Tuy nhiên, tôi không chắc chắn làm thế nào để xử lý kịch bản mà một phương thức được cung cấp bởi một tài nguyên JAX-RS yêu cầu một giao dịch, ảnh hưởng đến mô hình JPA get, update, commit-on-tx-end, vì chỉ có một gói giao dịch hoạt động nhận được, vì vậy bản cập nhật không bao giờ được cam kết. Tôi có thể thấy cùng một vấn đề xảy ra nếu một hoạt động REST đơn yêu cầu nhiều hoạt động JPA.

Khi tôi đang sử dụng hỗ trợ giao dịch của Spring, điều hiển nhiên cần làm là áp dụng @Transactional cho các phương pháp này trong tài nguyên JAX-RS. Tuy nhiên, để làm việc này, Spring cần quản lý vòng đời của các tài nguyên JAX-RS, và các ví dụ về số dặm mà tôi biết là có các tài nguyên được tạo ra thông qua 'mới' khi cần, điều này làm tôi hơi lo lắng.

tôi có thể nghĩ đến các giải pháp sau:

  1. cập nhật các phương pháp JPA tôi để cung cấp một phiên bản giao dịch được quản lý của tất cả mọi thứ tôi muốn làm từ giao diện REST của tôi nguyên tử. Nên làm việc, giữ các giao dịch ra khỏi lớp JAX-RS, nhưng ngăn chặn mẫu get, update, commit-on-tx-end và có nghĩa là tôi cần tạo một giao diện JPA rất chi tiết.
  2. Tiêm các đối tượng tài nguyên; nhưng họ thường nắm giữ ít nhất ID của đối tượng đang tương tác với
  3. Mương thứ bậc tài nguyên và tiêm các tài nguyên siêu lớn, không quốc tịch ở gốc quản lý toàn bộ phân cấp từ gốc đó; không liên kết, các dịch vụ lớn
  4. Có một hệ thống phân cấp các đối tượng trợ giúp được hỗ trợ giao dịch, không quốc tịch, được "che" các tài nguyên thực tế; các tài nguyên được khởi tạo và giữ trạng thái nhưng ủy quyền các phương thức invocations cho các đối tượng trợ giúp

Bất cứ ai có bất cứ đề xuất nào? Nó khá có thể tôi đã bỏ lỡ một số điểm chính ở đâu đó.


Cập nhật - để làm việc xung quanh việc thiếu một giao dịch quanh get, cập nhật, cam-on-tx-gần dòng chảy, tôi có thể tiếp xúc với phương pháp EntityManager merge (object) và gọi nó bằng tay. Không gọn gàng và không giải quyết được vấn đề lớn hơn.


Cập nhật 2 @skaffman Mã dụ: Trong lớp dịch vụ JPA, tiêm, các chú thích làm việc

public class MyEntityJPAService { 
... 
@Transactional(readOnly=true) // do in transaction 
public MyEntity getMyEntity(final String id) { 
    return em.find(MyEntity.class, id); 
} 

Trong tài nguyên JAX-RS, được tạo ra bởi mới, không có giao dịch

public class MyEntityResource { 
... 
private MyEntityJPAService jpa; 
... 
@Transactional // not injected so not effective 
public void updateMyEntity(final String id, final MyEntityRepresentation rep) { 
    MyEntity entity = jpa.getMyEntity(id); 
    MyEntity.setSomeField(rep.getSomeField()); 
    // no transaction commit, change not saved... 
} 

Trả lời

4

Tôi có một vài đề xuất

  1. Giới thiệu một lớp giữa các lớp JPA và JAX-RS của bạn. Lớp này sẽ bao gồm các hạt đậu @Transactional do Spring quản lý và sẽ soạn các hoạt động cấp doanh nghiệp khác nhau từ các cuộc gọi JPA thành phần của chúng. Điều này hơi giống với (1) của bạn, nhưng giữ cho lớp JPA đơn giản.

  2. Thay JAX-RS với Spring MVC-, cung cấp giống nhau (hoặc tương tự) chức năng, bao gồm @PathVariable, @ResponseBody vv

  3. lập trình quấn đối tượng JAX-RS của bạn trong proxy giao dịch sử dụng TransactionProxyFactorybean. Thao tác này sẽ dò tìm các chú thích @Transactional của bạn và tạo proxy ủy quyền cho chúng.

  4. Sử dụng @Configurable và AspectJ LTW để cho phép Spring tôn vinh @Transactional ngay cả khi bạn tạo đối tượng bằng cách sử dụng 'mới. Xem 8.8.1 Using AspectJ to dependency inject domain objects with Spring

+0

Những đề xuất này có được sắp xếp theo thứ tự ưu tiên (theo bạn) không? – brainOverflow

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