2014-04-17 10 views
27

Trường hợp1

@Transactional 
public class UserServiceImpl implements UserService { 

    ................... 
    public void method1(){ 
     try{ 
      method2(); 
     }catch(Exception e){ 

     } 
    } 
    public void method2(){ 

    } 
} 

Trường hợp2

public class UserServiceImpl implements UserService { 

    ................... 
    public void method1(){ 
     try{ 
      method2(); 
     }catch(Exception e){ 

     } 
    } 
    @Transactional 
    public void method2(){ 

    } 
} 

Trong Trường hợp1 là gì nếu có ngoại lệ xảy ra nó rollback đang làm việc, nhưng trong trường hợp 2 nó không làm việc. Có vấn đề về hiệu suất nào nếu tôi làm theo trường hợp 1 không?sự khác biệt giữa quy định @Transactional trên lớp vs phương pháp

Trả lời

10

Trích dẫn từ here

khuyến nghị Nhóm nghiên cứu của Spring là bạn chỉ chú thích các lớp bê tông với chú thích @Transactional, như trái ngược với chú thích giao diện.

Vì cơ chế này dựa trên proxy, chỉ các cuộc gọi phương thức 'bên ngoài' đến thông qua proxy sẽ bị chặn. Điều này có nghĩa là 'tự viện dẫn', tức là một 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 một giao dịch thực sự trong thời gian chạy ngay cả khi phương thức được gọi được đánh dấu bằng @Transactional!

+5

Điều này không chỉ sự khác biệt giữa phương thức được chú thích '@ Transactional' và' @ Transactional'. –

+1

@kocko> Tôi nghĩ OP sẽ theo liên kết, tuy nhiên tôi vừa mới cập nhật câu trả lời của mình, vui lòng xem qua. – mok

24

@Transactional trên lớp học áp dụng cho từng phương pháp trên dịch vụ. Đó là một lối tắt. Thông thường, bạn có thể đặt @Transactional(readonly = true) trên một lớp dịch vụ, nếu bạn biết rằng tất cả các phương thức sẽ truy cập vào lớp kho lưu trữ. Sau đó, bạn có thể ghi đè hành vi bằng @Transactional về các phương pháp thực hiện các thay đổi trong mô hình của mình. Vấn đề hiệu suất giữa 1) và 2) không được biết.

5

Giả sử bạn có các lớp sau:

@Transactional(readOnly = true) 
public class DefaultFooService implements FooService { 

    public Foo getFoo(String fooName) { 
    // do something 
    } 

    // these settings have precedence for this method 
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) 
    public void updateFoo(Foo foo) { 
    // do something 
    } 
} 

Các @Transactional chú thích vào mức độ lớp sẽ được áp dụng cho mọi phương thức trong lớp.

Tuy nhiên, khi một phương thức được chú thích bằng @Transactional) điều này sẽ được ưu tiên hơn cài đặt giao dịch được xác định ở cấp lớp.

Thông tin thêm:

11

Trong trường hợp 1 @Transactional được áp dụng cho mọi phương pháp cá nhân. Trong trường hợp 2 @Transactional chỉ được áp dụng cho phương thức 2(), không phải trên phương thức1()

Trường hợp 1: - Gọi phương thức1() -> một giao dịch được bắt đầu. Khi method1() gọi method2() không có giao dịch mới nào được bắt đầu, bởi vì đã có một

Trường hợp 2: - Phương thức gọi1() -> không có giao dịch nào được bắt đầu. Khi method1() gọi phương thức 2() NO giao dịch mới được bắt đầu. Điều này là do @Transactional không hoạt động khi gọi một phương thức từ bên trong cùng một lớp. Nó sẽ hoạt động nếu bạn gọi method2() từ một lớp khác.

Từ spring reference manual:

Trong chế độ proxy (đó là mặc định), chỉ có phương pháp bên ngoài các cuộc gọi đến trong thông qua các proxy được chặn. Điều này có nghĩa là tự gọi, trong thực tế, một phương thức trong đối tượng đích gọi một phương thức khác của đối tượng đích, sẽ không dẫn đến một giao dịch thực sự trong thời gian chạy ngay cả khi phương thức được gọi được đánh dấu bằng @Transactional. Ngoài ra, proxy phải được khởi tạo đầy đủ để cung cấp hành vi mong đợi, do đó bạn không nên dựa vào tính năng này trong mã khởi tạo của bạn, tức là @PostConstruct.

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