Tầng Service và Quản lý Transaction trong Spring Boot
Chào mừng bạn đến với bài viết số 6 trong loạt bài về Spring và Spring Boot. Hôm nay, chúng ta sẽ khám phá tầng Service. Nó đóng vai trò quan trọng trong kiến trúc ứng dụng. Chúng ta cũng sẽ tìm hiểu về quản lý transaction.
Kiến trúc 3 lớp: Controller, Service, Repository
Kiến trúc 3 lớp là một mô hình phổ biến. Nó giúp tổ chức code một cách rõ ràng. Các lớp bao gồm Controller, Service và Repository.
Controller tiếp nhận yêu cầu từ người dùng. Sau đó, nó chuyển yêu cầu đến tầng Service.
Service chứa logic nghiệp vụ của ứng dụng. Nó xử lý dữ liệu và thực hiện các tác vụ phức tạp.
Repository tương tác trực tiếp với cơ sở dữ liệu. Nó thực hiện các thao tác CRUD (Create, Read, Update, Delete).
Sự phân chia này giúp ứng dụng dễ bảo trì và mở rộng.
Tầm quan trọng của @Service
@Service là một annotation trong Spring. Nó đánh dấu một class là một Service component. Spring container sẽ quản lý lifecycle của các Service bean.
Sử dụng @Service mang lại nhiều lợi ích. Nó giúp tách biệt logic nghiệp vụ khỏi Controller và Repository. Nó cũng giúp code dễ test hơn.
Ví dụ, bạn có thể có một UserService. Nó chịu trách nhiệm xử lý các nghiệp vụ liên quan đến người dùng. Như tạo tài khoản, cập nhật thông tin, và xác thực.
Annotation @Service giúp Spring tự động phát hiện và quản lý bean này.
Giới thiệu về @Transactional
@Transactional là một annotation quan trọng khác trong Spring. Nó giúp quản lý transaction trong cơ sở dữ liệu. Transaction đảm bảo tính toàn vẹn dữ liệu.
Khi một phương thức được đánh dấu @Transactional, Spring sẽ bắt đầu một transaction trước khi phương thức được thực thi. Nếu phương thức thực thi thành công, transaction sẽ được commit. Nếu có lỗi xảy ra, transaction sẽ được rollback.
Điều này đảm bảo rằng các thay đổi dữ liệu là atomic. Hoặc là tất cả thành công, hoặc là không có thay đổi nào được thực hiện.
Ví dụ, bạn có thể có một phương thức để chuyển tiền từ tài khoản này sang tài khoản khác. Nếu một trong hai thao tác (rút tiền hoặc nạp tiền) thất bại, transaction sẽ được rollback để đảm bảo số tiền không bị mất.
@Transactional có nhiều thuộc tính để tùy chỉnh. Ví dụ, bạn có thể chỉ định isolation level và propagation behavior.
Ví dụ minh họa
Giả sử chúng ta có một ứng dụng quản lý sách. Chúng ta có các lớp sau:
BookController: Xử lý các yêu cầu liên quan đến sách.BookService: Chứa logic nghiệp vụ liên quan đến sách. Ví dụ: thêm sách mới, tìm kiếm sách, cập nhật thông tin sách.BookRepository: Tương tác với cơ sở dữ liệu để lưu trữ và truy xuất thông tin sách.
Trong BookService, chúng ta có thể có một phương thức để thêm sách mới. Phương thức này có thể được đánh dấu @Transactional để đảm bảo tính toàn vẹn dữ liệu.
@Service
public class BookService {
@Autowired
private BookRepository bookRepository;
@Transactional
public Book addBook(Book book) {
// Kiểm tra tính hợp lệ của dữ liệu
if (book.getTitle() == null || book.getTitle().isEmpty()) {
throw new IllegalArgumentException("Title cannot be empty");
}
// Lưu sách vào cơ sở dữ liệu
return bookRepository.save(book);
}
}
Trong ví dụ này, nếu quá trình lưu sách vào cơ sở dữ liệu gặp lỗi, transaction sẽ được rollback. Điều này đảm bảo rằng không có dữ liệu không hợp lệ nào được lưu trữ.
Cấu hình Transaction Management
Để sử dụng @Transactional, bạn cần cấu hình transaction management trong Spring. Bạn có thể sử dụng annotation @EnableTransactionManagement trong class cấu hình của bạn.
@Configuration
@EnableTransactionManagement
public class AppConfig {
// Cấu hình khác
}
Bạn cũng cần cấu hình một DataSource và TransactionManager.
Transaction Propagation
Transaction propagation xác định cách các transaction được xử lý khi một phương thức được gọi từ một phương thức khác đã có transaction.
Spring cung cấp nhiều propagation behavior khác nhau. Ví dụ:
REQUIRED: Nếu một transaction đã tồn tại, phương thức sẽ tham gia vào transaction đó. Nếu không có transaction nào tồn tại, một transaction mới sẽ được tạo.REQUIRES_NEW: Luôn tạo một transaction mới. Nếu một transaction đã tồn tại, nó sẽ bị tạm ngưng.SUPPORTS: Nếu một transaction đã tồn tại, phương thức sẽ tham gia vào transaction đó. Nếu không có transaction nào tồn tại, phương thức sẽ được thực thi mà không có transaction.NOT_SUPPORTED: Phương thức sẽ được thực thi mà không có transaction. Nếu một transaction đã tồn tại, nó sẽ bị tạm ngưng.MANDATORY: Phương thức phải được thực thi trong một transaction. Nếu không có transaction nào tồn tại, một exception sẽ được thrown.NEVER: Phương thức không được thực thi trong một transaction. Nếu một transaction đã tồn tại, một exception sẽ được thrown.
Bạn có thể chỉ định propagation behavior trong annotation @Transactional.
Isolation Level
Isolation level xác định mức độ cô lập giữa các transaction khác nhau.
Spring hỗ trợ các isolation level sau:
DEFAULT: Sử dụng isolation level mặc định của cơ sở dữ liệu.READ_COMMITTED: Chỉ cho phép đọc dữ liệu đã được commit.READ_UNCOMMITTED: Cho phép đọc dữ liệu chưa được commit (dirty read).REPEATABLE_READ: Đảm bảo rằng một transaction có thể đọc cùng một dữ liệu nhiều lần mà không bị thay đổi bởi các transaction khác.SERIALIZABLE: Mức độ cô lập cao nhất. Đảm bảo rằng các transaction được thực thi tuần tự.
Bạn có thể chỉ định isolation level trong annotation @Transactional.
Kết luận
Tầng Service và quản lý transaction là những khái niệm quan trọng trong Spring Boot. Tầng Service chứa logic nghiệp vụ của ứng dụng. @Transactional đảm bảo tính toàn vẹn dữ liệu. Hiểu rõ và áp dụng chúng sẽ giúp bạn xây dựng các ứng dụng mạnh mẽ và đáng tin cậy hơn. Hãy tiếp tục khám phá các khía cạnh khác của Spring Boot để trở thành một nhà phát triển thành thạo.
0 Bình luận
Vui lòng đăng nhập để gửi bình luận.