2011-11-09 32 views
7

Tôi có một lớp @Service có phương thức @Transactional gọi phương thức @Transactional khác trên cùng một lớp. Tôi đã thử nghiệm hành vi rollback cho điều này và tôi thấy rằng nó không hoạt động đúng. Mã trông giống như sau:Phương thức @Transactional lồng nhau trong mùa xuân và khôi phục

@Service 
public class DefaulService implements ervice 
{ 
    @Transactional 
    public void methodOne() 
    { 
     methodTwo(); 

      //question edited 
      //this seems to be the problem 
      this.serviceDAO.executeUpdateOperation(); 

     //test rollback 
     throw new RuntimeException(); 
    } 

    @Transactional 
    public void methodTwo() 
    { 
     //DAO stuff 
    } 
} 

Sau khi chạy phương phápMột lần đăng nhập cho thấy "JDBCTransaction - rollback".

Nếu tôi gọi methodTwo riêng lẻ và thêm ngoại lệ vào cuối, thay đổi sẽ được cuộn lại chính xác.

Có cách nào để thực hiện methodOne thay đổi rollback đúng xảy ra trong cuộc gọi @Transactional lồng nhau không? Tôi đã được ấn tượng rằng việc tuyên truyền mặc định của REQUIRED sẽ đạt được điều này, nhưng nó dường như không hoạt động. Cảm ơn

CẬP NHẬT

Ok, tôi chỉ nhận thấy cái gì khác. Ngay trước khi ném ngoại lệ, tôi đang gọi dao của dịch vụ và thực hiện cập nhật thủ công qua 'executeUpdate'. Nếu tôi bình luận dòng này, các rollback lồng nhau hoạt động. Vì vậy, có vẻ như vấn đề là thực sự gọi DAO và chạy truy vấn executeUpdate. Nhưng không nên điều này cũng chạy bên trong giao dịch hiện tại?

+0

Bạn có biết rằng khi gọi phương thức 'methodTwo()' từ 'methodOne()' '@ Transactional' trên chú thích cũ bị bỏ qua không? Xem [bài viết] của tôi (http://nurkiewicz.blogspot.com/2011/10/spring-pitfalls-proxying.html) để biết thêm chi tiết. Tuy nhiên điều này không gây ra vấn đề của bạn, nhưng đáng để biết. –

+0

Có, nhưng vì MethodTwo có thể được gọi độc lập, sau đó nó cần chú thích riêng cho các trường hợp như vậy. Ngay bây giờ tôi stumped là tại sao executeUpdate gây ra các giao dịch được cam kết, mặc dù có lẽ đó là hành vi mặc định. – JayPea

+1

tuyên truyền giao dịch của serviceDao là gì? Có phải là do REQUIRES_NEW cơ hội nào không? – Hendrik

Trả lời

1

Bạn chắc chắn có được ví dụ về "ervice" từ nhà máy đậu khi bạn gọi các phương thức, phải không? Nhà máy đậu cần thiết lập một proxy thực hiện logic giao dịch xung quanh mỗi cuộc gọi phương thức. Tôi đã ấn tượng rằng điều này chỉ hoạt động khi "người ngoài" gọi các phương thức thông qua proxy, và không nhất thiết phải làm việc khi một phương thức gọi khác, vì phương thức đó là một cuộc gọi trực tiếp bên trong đối tượng thực hiện và không đi qua proxy AOP.

+0

Điều này tùy thuộc vào loại phương pháp AOP bạn đang sử dụng. Kiểm tra [link] (http://nurkiewicz.blogspot.com/2011/10/spring-pitfalls-proxying.html) từ Tomasz Nurkiewicz. Ngoài ra điều đó không thể giải thích được hành vi mà JayPea đang mô tả. –

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