2017-12-10 130 views
8

Có một thực thể:mùa xuân dữ liệu: rollback giao dịch trên retry

@Entity 
class A { 
    ... 
    @Version 
    int version; 
} 

A trường cập nhật được thực hiện theo cách lạc quan:

@Transactional(rollbackFor = {StaleStateException.class}) 
@Retryable(value = {StaleStateException.class}) 
public void updateA() { 
    A a = findA(); 
    B b = new B(); 
    // Update "a" somehow 
    a.update(); 
    // "b" is saved on each retry! 
    save(b); 
} 

Như đã nêu trong bình luận, dường như giao dịch mà không rollbacked khi StaleStateException xảy ra, vì vậy ví dụ B được lưu trên mỗi lần thử lại.

Có thể quay lại giao dịch khi thử lại không?

Hành vi mong muốn là b chỉ được lưu trên bản cập nhật thành công a.

Trả lời

7

Tôi nghĩ nó có thể liên quan đến cấu hình @Retryable.

Do tài liệu cho biết https://docs.spring.io/spring-batch/trunk/reference/html/retry.html#statelessRetry một lần thử lại không có trạng thái là không có gì hơn một chu kỳ tiếp tục gọi cùng một phương thức cho đến khi nó thành công.

Vấn đề là mỗi lần nó không chặn thiết bị chặn đầu tiên được gọi là bộ lặp lại sẽ không trả về ngoại lệ, vì vậy nó không bao giờ đạt đến số @Transactional.

Vì vậy, điều xảy ra là mọi lần thử lại sẽ thực hiện theo tuyên truyền giao dịch mặc định sẽ sử dụng lại giao dịch đã mở cùng với new B() trong ngữ cảnh.

Bạn có thể kiểm tra xem tôi có đang dẫn đầu đúng không bằng cách gỡ lỗi: nếu bạn nhập lần thử thứ hai và thấy rằng A đã được cập nhật trước khối cập nhật thì tôi nên làm đúng.

Bạn có thể sửa theo 2 cách:

Hoặc chia hai khối (thử đầu tiên với giao dịch lồng nhau)

@Retryable(value = {StaleStateException.class}) 
public void retryableUpdate() { 
    updateA(); 
} 

@Transactional(rollbackFor = {StaleStateException.class}) 
public void updateA() { 
    A a = findA(); 
    B b = new B(); 
    // Update "a" somehow 
    a.update(); 
    // "b" is saved on each retry! 
    save(b); 
} 

Vì vậy mà giao dịch được cuộn lại đầu tiên.

Hoặc bạn có thể theo dõi tài liệu và sử dụng thử lại trạng thái https://docs.spring.io/spring-batch/trunk/reference/html/retry.html#statefulRetry

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