2013-11-25 20 views
8

Tôi có một ứng dụng JavaEE sử dụng Hibernate để kết nối với cơ sở dữ liệu. Trong một số phần của ứng dụng của tôi, tôi có các cuộc gọi đến phương thức có chú thích @Transactional. Trong một số trường hợp này, tôi muốn khôi phục toàn bộ giao dịch (cuộc gọi phương thức dịch vụ bên ngoài và bên trong). Và trong một số trường hợp, tôi muốn khôi phục chỉ cuộc gọi phương thức dịch vụ bên trong (nghĩa là, quay lại savepoint được xác định khi bắt đầu phương thức nội bộ).Cách quay trở lại các giao dịch lồng nhau lưu trữ bằng Hibernate

Phần đầu tiên đã có sẵn, nhưng tôi gặp vấn đề với phiên bản thứ hai. Khi tôi làm như sau, tôi nhận được một "UnexpectedRollbackException" với thông báo "Transaction roll back vì nó đã được đánh dấu là rollback-only".

@Service 
public class OuterService{ 

    @AutoWired 
    private InnerServcie innerService; 

    @Transactional 
    public void outer(){ 
     try{ 
      innerService.inner(); 
     }catch(RuntimeException e){ 
      //if i dont throw this up, it will give me the "UnexpectedRollbackException" 
      System.out.println("I cought a RuntimeException"); 
     } 
    } 
} 

@Service 
public class InnerServcie{ 
    @Transactional 
    public void inner(){ 
     //here we insert some data into db using hibernate 
     //but something goes wrong and an exception is thrown 
    } 
} 

Trả lời

0

Không có hỗ trợ cho các giao dịch lồng nhau trong Spring/Hibernate/Java EE. Vì vậy, hoặc toàn bộ điều được khôi phục, hoặc giao dịch bên trong thực sự là một giao dịch mới, khác nhau, sẽ được cam kết ngay sau khi nó thành công và thậm chí nếu giao dịch bên ngoài quay lại sau.

Nếu sau này là những gì bạn muốn, sau đó chỉ cần chú thích phương pháp bên trong của bạn với

@Transactional(propagation = Propagation.REQUIRES_NEW) 
+0

tôi thêm này với phương pháp bên trong, và tôi nhận được một bế tắc! Bất kỳ ý tưởng? – hfm

6

Tính năng bạn đang tìm kiếm được gọi là điểm lưu giữ. Họ không, nói đúng, các giao dịch lồng nhau, nhưng các mốc quan trọng trong chuỗi lệnh SQL kết quả, mà bạn có thể khôi phục. Quay trở lại điểm lưu trữ có nghĩa là vô hiệu hóa TẤT CẢ hướng dẫn được tạo từ thời điểm tạo điểm lưu trữ, vì vậy bạn có thể có nhiều điểm lưu, nhưng bạn chỉ có thể quay lại hướng dẫn giữa bây giờsavepoint, không phải giữa 2 điểm lưu!

Spring hỗ trợ các điểm lưu, cả khi sử dụng JdbcTransactionObjectSupport theo cách thủ công và sử dụng chú thích @Transactional.

Theo tài liệu http://docs.spring.io/spring/docs/2.5.3/reference/transaction.html điểm 9.5.7.3 bạn nên sử dụng Propagation.NESTED.

Tuy nhiên, các tùy chọn đó có thể không khả dụng trong trường hợp của bạn. Từ Javadoc:

Lưu ý: Việc tạo thực tế giao dịch lồng nhau sẽ chỉ hoạt động trên người quản lý giao dịch cụ thể. Ngoài hộp, điều này chỉ áp dụng cho JDBC DataSourceTransactionManager khi làm việc trên trình điều khiển JDBC 3.0 . Một số nhà cung cấp JTA cũng có thể hỗ trợ các giao dịch lồng nhau.

Như phương sách cuối cùng, bạn có thể đưa ra hướng dẫn SQL bắt đầu/rollbacking để lưu điểm trực tiếp.

Đối với PostgreSQL nó sẽ là:

SAVEPOINT foo; 

ROLLBACK TO SAVEPOINT foo; 

Nguồn: http://www.postgresql.org/docs/8.2/static/sql-rollback-to.html

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