Avatar
1
Nguyễn Thái Sơn Professional
Nguyễn Thái Sơn Professional
tránh deadlock với Transaction trong Database
Anh ơi, khi 1 ứng dụng có 2 thread Update  2 bảng A đến B và B đến A với cùng 1 record sẽ xảy ra deadlock, điều này không tránh khỏi. 2 thread sẽ chờ nhau nhả khoá dẫn đến cả 2 transaction không bao giờ được commit. Vậy khi gặp trường hợp này anh làm cách nào ngoài việc restart Database. Để tránh deadlock, đa số mọi người sẽ khuyên các thao tác update Database trong 1 transaction luôn cùng thứ tự, ví dụ như A đến B như trong ví dụ trên. Như vậy với 1 hệ thống hàng chục, hàng trăm bảng khi ta làm việc với Transaction, muốn tránh deadlock thì  dev phải quy ước phải update bảng nào trước bảng nào, như vậy liệu có ổn không ạ. Người developer sẽ phải ghi nhớ, kiểm tra nên update bảng nào trước, bảng nào. Anh có phương án nào cho việc này không ạ
  • Answer
database transaction deadlock
Remain: 5
2 Answers
Avatar
monkey Professional
monkey Professional

Anh ơi, khi 1 ứng dụng có 2 thread Update 2 bảng A đến B và B đến A với cùng 1 record sẽ xảy ra deadlock, điều này không tránh khỏi

Anh chưa hiểu cái này lắm, em có thể ví dụ cụ thể bằng code được không?

Trong mọi trường hợp thì việc deadlock đều dẫn đến service bị hoạt động không bình thường. Khi em sử dụng database thì tuỳ theo cơ chế của database đó nó sẽ đối xử với transaction thế nào. Có thể là nó sẽ có timeout cho transaction, có thể là nó sẽ đóng lại transaction khi session bị ngắt kết nối, vậy nên sẽ không nhất thiết em phải restart database đâu.

Để tránh deadlock thì em có thể tham khảo wiki này. Và cách đơn giản nhất là đừng có sử dụng synchronized hoặc lock bừa bãi, và trong code thực tế thì em cũng hiếm khi sử dụng đến lock, ngay cả khi có sử dụng lock thì thường em cũng dùng trong phạm vi nhỏ hoặc không lồng nhau, nên cũng không cần lo lắng quá về deadlock đâu em ạ.

  • 0
  • Reply
Avatar
Có thể e đang nói về cycle deadlock, nếu như vậy thì thường sẽ KHÔNG có một cách nào hoàn toàn tránh được, cách tốt nhất (đối với các hệ thống lớn trong vd của e) đúng như e nói. Nếu A rồi đến B thì trước khi gọi A phải lock B trước.

Hoặc một cách khác là lock row-level thay vì table-level, và cấp độ lock là READ COMMITED, nhưng cách này ko loại bỏ hoàn toàn rủi ro xảy ra cycle deadlock được

  • 0
  • Reply