2011-12-11 21 views
25

Gần đây tôi đã bắt đầu làm việc với JPA trên Google App Engine. Khi đọc một số ví dụ, tôi đã nhận thấy một vài biến thể trong cách đối tượng được tiếp tục tồn tại. Trong một trường hợp, tôi đã thấy một cái gì đó như thế này:JPA - Khi nào sử dụng getTransaction() khi lưu giữ các đối tượng

entityManager.getTransaction().begin(); 
entityManager.persist(object); 
entityManager.getTransaction().commit(); 

Trong các trường hợp khác, tôi không thấy sử dụng getTransaction(). Tôi chỉ đơn giản nhìn thấy entityManager.persist (đối tượng). Khi nào nó thích hợp để sử dụng getTransaction()?

Trả lời

14

Nếu bạn sử dụng vùng chứa được quản lý EntityManager thì bạn đang sử dụng giao dịch JTA. Do đó, bạn không cần phải (chính xác hơn - bạn không thể) can thiệp vào các giao dịch của EntityManager được tìm nạp bằng cách sử dụng entityManager.getTransaction(). JTA bắt đầu và cam kết giao dịch của bạn.

Nếu bạn sử dụng ứng dụng được quản lý EntityManager và bạn không muốn tham gia giao dịch JTA, thì bạn cần quản lý chúng cho chính mình (nó được gọi là người quản lý thực thể địa phương).

Thông thường nhất, ứng dụng được quản lý EntityManager hoạt động với EntityManager.getTransaction() được sử dụng trong môi trường Java SE.

EDIT: Bạn có thể quan tâm đến secion 7.5 Kiểm soát các giao dịch từ JPA 2.0 specification.

+2

GAE không hỗ trợ JTA. –

+0

Không bao giờ làm việc với GAE - nghĩ rằng đây là câu hỏi trung tâm giao dịch JPA hơn. Cảm ơn bạn đã làm rõ. –

+1

chúng ta có cần giao dịch ngay cả khi nhận thực thể từ cơ sở dữ liệu ... sử dụng phương thức entitymanager.find ... chỉ tò mò..bởi vì tôi không thể thấy ngay cả một ví dụ đơn lẻ.với transaction.begin() trước entitymanger.find method ... :) :) – goodyzain

0

Bạn muốn sử dụng getTransaction() khi bạn xử lý rõ ràng các giao dịch trong ứng dụng của mình. Mặt khác, nếu bạn để cho vùng chứa xử lý các giao dịch cho bạn, sẽ không cần thiết phải bắt đầu/kết thúc giao dịch một cách rõ ràng. Về cơ bản, chúng tôi đang xử lý sự khác biệt giữa Container Managed Transactions (CMT) và Bean Managed Transactions (BMT). Nói chung, bạn nên sử dụng BMT khi bạn cần kiểm soát nhiều hơn về xử lý giao dịch, hoặc khi có các yêu cầu kỹ thuật bổ sung (ví dụ, cam kết hai pha, giao dịch phân phối, giao dịch XA) không thể đáp ứng được bằng cách sử dụng CMT. Ngoài ra, bạn sẽ sử dụng BMT khi các ứng dụng của bạn được triển khai bên ngoài một máy chủ ứng dụng và dựa trên Java SE.

5

Trong GAE không có Java EE/JTA nên bỏ qua các thuật ngữ như giao dịch quản lý bean (BMT) và giao dịch được quản lý container (CMT). Công việc của bạn là giao dịch (nơi bạn muốn nhiều đối tượng đến kho dữ liệu cùng một lúc, hoặc tất cả thất bại - đây là nơi bạn có getTransaction() được sử dụng), hoặc không giao dịch (nơi mọi thứ được chuyển đến kho dữ liệu bởi một, và sự thất bại của một tồn tại không ảnh hưởng đến người khác - đây là nơi bạn chỉ cần gọi persist()/merge()/remove()).

+1

Có một số phần của Java EE trong GAE, không phải là bất kỳ cấu hình hoàn chỉnh nào. Ví dụ JPA là một API Java EE, nhưng hành vi của nó là một chút khác biệt. –

3

Google App Engine có quản lý giao dịch (https://developers.google.com/appengine/docs/java/datastore/transactions) nhưng giao diện giao dịch JPA không nhận thức được một số chức năng cơ bản của GAE (tức là nhóm tổ chức).

Vì vậy, tùy thuộc vào ứng dụng của bạn để quyết định hoạt động nào sẽ thực hiện trong giao dịch và không. Bạn nên đặt trong một hoạt động giao dịch phải được thực thi một cách nguyên tử.

Hãy nhớ thực hành tốt nhất để thực hiện các hoạt động xếp tầng và hoạt động mối quan hệ trong giao dịch vì JPA có thể kích hoạt nhiều truy vấn và có thể dẫn đến tình trạng dữ liệu không nhất quán.

Ví dụ về sử dụng giao dịch với JPA2:

import javax.persistence.EntityTransaction; 


EntityTransaction txn = em.getTransaction(); 
txn.begin(); 
try { 
    //do something with your database 
    txn.commit(); 
} 
finally { 
    if (txn.isActive()) 
     txn.rollback(); 
} 
Các vấn đề liên quan