Avatar
0
Dev Mới Beginner
Dev Mới Beginner
Không hiểu kiểu gì luôn?
Hi anh Dũng, cả nhà mình,

Em đang gặp vấn đề như sau:

Lưu 1 object xuống db, sau đó dùng id của object đó push vào kafka, đoạn code mô tả bên dưới:

var saveResult = this.repo.saveAndFlush(entity);

this.kafkaTemplate.send(topic, saveResult.getId());

Tuy nhiên khi listen topic trên thì thi thoảng vẫn có những trường hợp em gọi hàm findById bị not found.

Vậy có phải là việc listen topic trên diễn ra trước lúc transaction được commit ko nhỉ? Và cũng xin mọi người cách để giải quyết bài trên ạ

(Em đang dùng spring boot cả nhà ạ)

  • Answer
Remain: 5
2 Answers
Avatar
monkey Beginner
monkey Beginner
The Best Answer
Anh khá chắc chắn rằng em đang làm đúng và transaction cho việc insert dữ liệu đã thành công rồi, nên ở consumer em sẽ thấy được qua hàm findById. Như vậy có thể em đang bị lỗi logic nào đó, em kiểm tra lại xem nhé.
  • 0
  • Reply
Oh không biết đã có ai bị như em chưa, nhưng sau một hồi vắt óc suy nghĩ về trasaction em đoán rằng vì em đánh transaction cho hàm đó lên nó sẽ đợi khi push vào kafka xong nó mới commit, khi em bỏ transaction đi thì nó ok luôn anh ạ!

Kiểu:

@tran

Func:void {

doSave();

doPush();

}

Nó sữ thực hiện chạy full hàm xong rồi mới commit

Bình thường em cũng thuộc dạnh đánh transaction khá là kĩ lưỡng lên ko nghĩ ra được trường hợp này!

Hi vọng nó cũng là 1 bài học dành cho ae trong group, khá là hay :)

 –  Dev Mới 1714639393000
Em đang đưa nghiệp vụ bắn event vào transaction của db là một thiết kế không tốt và vi phạm nguyên tắc single reposibility em ạ  –  monkey 1714646764000
Vậy em phải thiết kế phần này sao cho hợp lý anh? anh có thể cho em những keyword hoặc những pattern để em tìm hiểu và áp dụng được ko?  –  Dev Mới 1714652366000
Annotation @Transactional của spring được tạo ra từ đời đầu, thời đó team chưa thấy được hết các vấn đề, còn người sử dụng thì cũng không tìm hiểu kỹ, thấy tiện thì dùng. Để cài đặt chính xác thì em cần sử dụng trực tiếp EntityTransaction kiểu này nhé: https://github.com/youngmonkeys/ezyplatform-development/blob/master/ezyplatform-sdk/ezyplatform-common-sdk/src/main/java/org/youngmonkeys/ezyplatform/repo/UserMetaTransactionalRepository.java  –  tvd12 1714662718000
Avatar
datconxanh Beginner
datconxanh Beginner
đúng goy, cái id kia chỉ là mới được tạo ra chứ chưa thực sự lưu xuống db,khi nào xong transaction thì mới commit và được đẩy vào db,đợt trc cx dính case này lúc mới đầu chưa biết debug khá ảo ma :)))
  • 0
  • Reply
Hehe thanks bác nha, ns chung là dùng transaction khó phết bác nhỉ :)  –  Dev Mới 1714652417000
theo mình hiểu thì mọi hàm thuộc jpa đều có transacton riêng , như vậy trường hợp của chủ tus là đặt thêm một trans bao ngoài ( bọc luôn tras nội tại jpa ) . Vậy theo ý chủ tus mình hiểu là nếu 2 trans lồng nhau thì , dữ liệu sẽ ăn theo trans to nhất ngoài cùng ạ ? @Dev Mới  –  l5fctuojcw8j0n1g 1714806625000
cái này dễ kiểm chứng mà b, bh bạn đánh trans ở trên đầu func xong trong func b gọi repository.save() xong bên dưới b throw ra lỗi thì b xem nó có roll back không là biết mà :))) @ l5fctuojcw8j0n1g  –  datconxanh 1714817529000