2013-04-27 17 views
5

Hãy nói rằng chúng ta có đoạn mã sau:Giao dịch mới có tách tất cả các thực thể trước đó không?

@Entity 
public class User { 
    @Id 
    private String name; 
    @OneToOne(cascade = CascadeType.ALL) 
    private Address address; 
    //getters and setters 
} 

@Entity 
public class Address { 
    @Id 
    private int id; 
    private String street; 
    //getters and setters 
} 

@Stateless 
//@Service 
public class UserLogicClass { 
    @PersistenceContext 
    //@Autowired 
    private EntityManager entityManager; 

    public void logicOnUser(User user) { 
     if(logicOnAddress(user.getAddress()) { 
      otherLogicOnUser(user); 
     } 
    } 

    public boolean logicOnAddress(Address address) { 
     // 
     entityManager.find(address);//address becomes managed 
     // 
    } 

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
    //@Transactional(propagation = Propagation.REQUIRES_NEW) 
    public void otherLogicOnUser 
    // 
     entityManager.find(user);/*without annotation, user is not managed and address is managed, but with the transaction annotation is the address still managed?*/ 
    // 
    } 
} 

Câu hỏi đặt ra dựa vào những nhận xét từ phương pháp cuối cùng; Tôi là curios những gì xảy ra trong cả hai trường hợp mùa xuân và trường hợp EJB. Giả sử Spring được cấu hình với các giao dịch JTA và bất kỳ phương thức nào được gọi từ lớp này sẽ bắt đầu một giao dịch mới, giống như trong EJB.

Trả lời

5

Đó là vấn đề về JPA. Các EntityManager không tuyên truyền cho các giao dịch mới trừ khi bạn thực hiện nó mở rộng:

@PersistenceContext(type = PersistenceContextType.EXTENDED) 
//@Autowired 
private EntityManager entityManager; 

Trích dẫn từ thông số kỹ thuật JPA 2.0:

Một bối cảnh kiên trì container quản lý có thể được định nghĩa để có một trong hai một đời được scoped cho một giao dịch duy nhất hoặc một thời gian mở rộng kéo dài nhiều giao dịch, tùy thuộc vào PersistenceContextType được chỉ định khi trình quản lý đối tượng của nó được tạo . Đặc điểm kỹ thuật này đề cập đến các bối cảnh bền vững như là các ngữ cảnh kiên trì giao dịch có phạm vi giao dịch và mở rộng sự kiên trì tương ứng ngữ cảnh.

+0

Vì vậy, trừ các loại được thiết lập để mở rộng, bên trong phương pháp đó, một người quản lý thực thể mới được tạo ra, mà không có bất kỳ cơ quan quản lý? – m3th0dman

+1

Vâng, chính xác. Trong phương thức 'otherLogicOnUser', một giao tác mới được tạo và bối cảnh persistence không nên được nhân rộng trừ khi bạn mở rộng nó. – dcernahoschi

+0

Sử dụng EntityManager mở rộng được thiết kế để sử dụng trong Stateful EJB, nó không phải là luồng an toàn, và các xung đột bối cảnh tồn tại có thể phát sinh nếu một phương thức sử dụng EntityManager giao dịch được gọi ra bằng cách sử dụng một EntityManager mở rộng trong cùng một giao dịch. – German

5

Lưu ý: Kể từ khi cơ chế này được dựa trên proxy, chỉ phương pháp 'bên ngoài' các cuộc gọi đến trong thông qua proxy sẽ bị chặn. Điều này có nghĩa là 'tự gọi', nghĩa là phương thức trong đối tượng đích gọi một số phương thức khác của đối tượng đích sẽ không dẫn đến giao dịch thực tế khi chạy ngay cả khi phương thức được gọi được đánh dấu bằng @Transactional!

otherLogicOnUser() được gọi bên trong đối tượng đích.

Read more: EJB Transactions in local method-calls

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