+4

Spring Boot Transactional - Lỗi hầu hết mọi người gặp phải

1. Giới thiệu vấn đề

Transaction đã được hỗ trợ trong Spring Boot Framework. Chỉ cần khai báo @Transactional trước method là xong như thế này. Theo như logic, khi có Exception xảy ra thì Transaction sẽ rollback lại các thao tác trước đó.

    @GetMapping("/get")
    @Transactional
    public void get() throws Exception {
        TestEntity testEntity = new TestEntity();
        testRepository.save(testEntity);
        throw new Exception("test");
    }

Như trong ví dụ trên, sẽ không lưu 1 bản ghi nào vào databases, nhưng thực tế data vẫn được lưu -> Vấn đề ở chỗ nào? Framework hoạt động sai?

2. Cách giải quyết vấn đề

Để giải quyết vấn đề này, ta đi đọc lại định nghĩa của @Transactional Trong khái niêm có đoạn

If no custom rollback rules apply, the transaction will roll back on RuntimeException and Error but not on checked exceptions

Nếu chúng ta không khai báo rollback rules thì transaction sẽ chỉ rool back khi có exception của RuntimeExceptionError. Còn các loại Checked Exceptions sẽ không được rollback

Có nhiều bạn không rõ về Checked vs Unchecked Exception xem ở đây

Có 2 cách cách giải quyết như sau:

2.1. Khai báo rollback rules

Có thể chọn 1 hay nhiều rules. Có thể dùng

    @GetMapping("/get2")
    @Transactional(rollbackFor = {Exception.class, Throwable.class})
    public void get2() throws Exception {
        TestEntity testEntity = new TestEntity();
        testRepository.save(testEntity);
        throw new Exception("test");
    }
    

2.2. Khi tạo lỗi, throw RunTimeExceptions hoặc Error

    @GetMapping("/get3")
    @Transactional
    public void get3() throws Exception {
        TestEntity testEntity = new TestEntity();
        testRepository.save(testEntity);
        throw new Error("test");
//        throw new RuntimeException("test");
    }

MÌnh thì thích làm theo cách 1. Khai báo tường minh rollBackFor, giúp kiếm soát dễ hơn.

3. Kết Luận

Đây là 1 lỗi rất cơ bản, nhiều lúc các testcases không cover được đẫn đến bỏ sót lỗi. Kể cả các bạn lập trình viên vài năm kinh nghiệm mà vẫn gặp phải. Nếu cần trao đổi hãy comment ở bên dưới.

Link Sourcecode


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí