2010-03-25 46 views
26

Ai có thể giải thích sự khác biệt giữa những gì là:chênh lệch giữa @Resource UserTransaction và EntityManager.getTransaction là gì()

@Resource 
UserTransaction objUserTransaction; 

EntityManager.getTransaction(); 

Và giao dịch cũng là những gì được quản lý container? và làm thế nào tôi nên làm điều đó trong mặt tiền phiên của tôi nếu tôi muốn chèn ba hàng trong bảng trong giao dịch.

+1

Bài viết hay để có ý tưởng tốt hơn về Giao dịch EJB, IMO, phải đọc http://entjavastuff.blogspot.com/2011/02/ejb-transaction-management-going-deeper.html – thirdy

Trả lời

26

EJB là các thành phần giao dịch. Giao dịch có thể được quản lý bởi chính máy chủ ứng dụng (CMT - giao dịch do container quản lý), hoặc tự tay bạn trong EJB (BMT - giao dịch được quản lý bằng bean).

EJB hỗ trợ giao dịch phân phối thông qua đặc tả JTA. Giao dịch phân phối được điều khiển bằng cách sử dụng UserTransaction, có phương thức begin, commit, rollback.

Với CMT, máy chủ ứng dụng bắt đầu, cam kết và khôi phục giao dịch (theo số transaction annotations) cho bạn và bạn không được phép can thiệp. Điều này có nghĩa là bạn không được truy cập vào số UserTransaction trong trường hợp này. Tuy nhiên, với BMT, bạn làm điều đó theo cách thủ công và bạn tự kiểm soát giao dịch bằng cách sử dụng UserTransaction.

Bây giờ hãy chuyển đến EntityManager. Việc triển khai JPA có thể được sử dụng trong máy chủ ứng dụng hoặc độc lập. Nếu sử dụng độc lập, bạn cần sử dụng EntityManage.getTransaction để tự mình phân định giao dịch JDBC. Nếu được sử dụng trong một máy chủ ứng dụng, thì EntityManager đã phối hợp với người quản lý giao dịch phân phối JTA một cách minh bạch cho bạn.

Hầu hết thời gian, bạn sử dụng CMT với chú thích @Required trên EJB. Điều này có nghĩa là bạn không cần truy cập vào số UserTransaction cũng không phải EntityManager.getTransaction. Ứng dụng. máy chủ bắt đầu và cam kết giao dịch, nhưng cũng phải cẩn thận để khôi phục nếu ngoại lệ được nâng lên. Đây là những gì tôi muốn giới thiệu cho mặt tiền của bạn.

(Có nhiều sự tinh tế hơn, chẳng hạn như PersistenceContextType hoặc hướng dẫn thủ công của người quản lý thực thể trong giao dịch phân phối với EntityManager.joinTransaction, nhưng đó chỉ khi bạn sử dụng công nghệ theo các cách khác nhau làm mặc định).

+3

Bạn có chắc chắn rằng 'EntityManager # getTransaction()' hợp tác với giao dịch phân phối JTA khi chạy bên trong một máy chủ ứng dụng? Tôi không nghĩ rằng nó làm, sự hiểu biết của tôi là nó trả về một giao dịch tài nguyên địa phương có thể được sử dụng để duy trì dữ liệu * bên ngoài * của giao dịch JTA hiện tại. –

+0

@Pascal 'EntityManager' hợp tác với JTA, do đó bạn không nên sử dụng' EntityManager # getTransaction'. Theo javadoc, 'EntityManager # getTransaction' ném' IllegalStateException' nếu được gọi trên một thực thể JTA EntityManager. – ewernli

+2

Thật vậy, 'getTransaction' ném một ngoại lệ khi được gọi trên một thực thể JTA EntityManager). Trên thực tế, ví dụ tôi có trong đầu (từ "Pro JPA 2") là để có được một ứng dụng EM được quản lý, tài nguyên cục bộ trong một Bean Session - ví dụ: để ghi nhật ký kiểm tra - và một giao dịch tài nguyên cục bộ mà bạn có thể bắt đầu/cam kết bao nhiêu thời gian như bạn muốn bên ngoài giao dịch JTA. Nhưng tôi nhận ra rằng tôi đã hiểu sai câu trả lời của bạn, điều này khác với những gì bạn viết. Cảm ơn! –

7

UserTransaction đề cập đến thực thể giao dịch JTA. Bạn sẽ chỉ có thể sử dụng điều này khi có một mô-đun JTA có sẵn trong máy chủ ứng dụng: ví dụ, nếu bạn đang triển khai một ứng dụng với điều này trên Tomcat (theo mặc định không hỗ trợ JTA), mã dựa vào điều này sẽ thất bại . Đây là loại giao dịch mặc định được sử dụng trong EJB và MDB.

EntityManager.getTransaction() truy xuất một thực thể giao dịch địa phương. Điều này đôi khi còn được gọi là giao dịch tài nguyên cục bộ.

Giao dịch tài nguyên cục bộ rất khác với giao dịch JTA: trong số các giao dịch khác, tài nguyên cục bộ dành riêng cho tài nguyên, trong khi giao dịch JTA có xu hướng cụ thể cho một chuỗi cụ thể.

Để biết thêm thông tin về sự khác biệt giữa tài nguyên giao dịch địa phương và JTA, thấy điều này Stackoverflow trả lời ở đây: What is the difference between a JTA and a local transaction?

0

Ngoài @ câu trả lời của Marco mà làm tốt để biết sự khác biệt giữa các JTA và tài nguyên giao dịch tại địa phương.

Giao dịch được quản lý vùng chứa được [do tên đó] quản lý bởi vùng chứa chứ không phải ứng dụng của bạn. Điều này được thực hiện thông qua tầng EJB, nơi bạn chỉ cần viết phương thức của bạn và vùng chứa sẽ bao bọc phương thức xung quanh ngữ cảnh giao dịch để nếu bất kỳ phần nào của phương thức của bạn hoặc các cuộc gọi cấp thấp hơn của nó ném ngoại lệ, giao dịch sẽ quay trở lại.

Nó cũng có thể được tinh chỉnh bằng chú thích. Bạn có thể tìm thêm thông tin tại đây https://docs.oracle.com/javaee/5/tutorial/doc/bncij.html

Lưu ý rằng điều này chỉ được thực hiện thông qua EJB và người quản lý thực thể được tiêm trên tầng web (ví dụ: servlets hoặc REST API) không được quản lý bởi vùng chứa trong trường hợp bạn phải tra cứu giao dịch bằng cách sử dụng số điện thoại @Resource UserTransaction hoặc EntityManager.getTransaction, begin()commit().

Từ Java EE 6, bạn được phép có EJB bên trong tầng web, do đó bạn không cần bố cục dự án quá phức tạp trừ khi bạn bắt đầu muốn hiển thị EJB của mình dưới dạng dịch vụ web.

+0

Trong các giao dịch được quản lý bởi EE container có sẵn bên ngoài EJB thông qua chú thích "@Transactional". –

+0

Giao dịch JTA là * không * nhất thiết là CMT, vì JTA có thể được sử dụng ngoài các máy chủ ứng dụng (hoặc "vùng chứa") với các thư viện như Bitronix và Atomikos. – Marco

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