Tôi nghĩ cách tốt nhất để xử lý điều này là sử dụng mẫu SELECT ... FOR UPDATE được mô tả ở đây:http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html
Để tham khảo:
SELECT counter_field FROM child_codes FOR UPDATE; UPDATE child_codes
SET counter_field = counter_field + 1;
...
Vì vậy, trong trường hợp của bạn, bạn sẽ thay thế
LOCK TABLES AlarmCount WRITE, AlarmMembership READ;
UPDATE AlarmCount SET num = num - 1
WHERE RuleId = OLD.RuleId AND
MemberId = 0 AND
IsResolved = OLD.IsResolved;
Với một cái gì đó như
SELECT num FROM AlarmCount WHERE RuleId = OLD.RuleId AND
MemberId = 0 AND
IsResolved = OLD.IsResolved FOR UPDATE;
UPDATE AlarmCount SET num = num - 1;
Tôi nói "đại loại như" bởi vì tôi không hoàn toàn rõ ràng đối với tôi những gì OLD.RuleId và OLD.IsResolved đang tham chiếu. Cũng đáng lưu ý từ http://dev.mysql .com / doc / refman / 5.0 / en / innodb-lock-read.html là:
UPDATE child_codes SET counter_field = LAST_INSERT_ID(counter_field +
1);
SELECT LAST_INSERT_ID();
Nói cách khác, bạn có thể có thể tối ưu hóa mô hình này hơn nữa bằng cách chỉ truy cập vào bảng một lần ... nhưng một lần nữa có một số chi tiết về lược đồ của bạn mà tôi không hoàn toàn tuân theo và tôi không chắc mình có thể cung cấp tuyên bố thực tế cho bạn ' d cần. Tuy nhiên, tôi nghĩ rằng nếu bạn xem CHỌN ... ĐỂ CẬP NHẬT, bạn sẽ thấy mô hình này tóm tắt lại nội dung gì và bạn cần làm gì để điều này hoạt động trong môi trường của bạn.
Tôi cũng nên đề cập rằng có một số môi trường công cụ lưu trữ và mức độ cách ly giao dịch mà bạn sẽ muốn xem xét. Có một cuộc thảo luận rất, rất hay về SO về chủ đề này ở đây: Khi nào sử dụng SELECT ... FOR UPDATE?
Hy vọng điều này sẽ hữu ích!