Cả hai đều dùng để lưu entity, nhưng khác nhau về thời điểm flush dữ liệu xuống database. Thuộc Spring Data JPA.
Bảng so sánh chi tiết
| STT | Tiêu chí | save() | saveAndFlush() |
|---|---|---|---|
| 1 | Thuộc Repository | CrudRepository |
JpaRepository (kế thừa CrudRepository) |
| 2 | Chiến lược flush | Không flush ngay. Chờ transaction commit hoặc gọi flush() thủ công |
Flush ngay lập tức xuống DB sau khi save |
| 3 | Bulk save | Hỗ trợ saveAll(Iterable) |
Không hỗ trợ bulk operation |
| 4 | Độ hiển thị dữ liệu | Thay đổi không hiển thị ngoài transaction cho đến khi commit/flush | Thay đổi hiển thị ngay ngoài transaction (vì đã flush) |
| 5 | Use case | Không cần dùng thay đổi ngay trong cùng transaction | Cần dùng thay đổi ngay trong cùng transaction (VD: trigger DB, stored proc, query tiếp) |
Minh họa luồng hoạt động
@Transactional
public void example() {
// save() - chưa hit DB
entity = repo.save(entity);
// entity đã có ID (nếu @GeneratedValue), nhưng chưa commit DB
// saveAndFlush() - hit DB ngay
entity = repo.saveAndFlush(entity);
// Dữ liệu đã có trong DB, transaction khác có thể thấy (nếu isolation level cho phép)
}
Lưu ý quan trọng
saveAndFlush()hữu ích khi cần ID sinh ra ngay, hoặc cần gọi stored procedure/trigger sau insert.- Lạm dụng
saveAndFlush()trong loop batch insert sẽ làm chậm hiệu suất nghiêm trọng (mỗi lần một round-trip DB). - Với batch insert: dùng
saveAll()+flush()thủ công sau khi tích lũy đủ batch size. - Cả hai đều trả về entity đã lưu (có ID populated).