2012-04-06 13 views
7

MongoDB hỗ trợ cập nhật nguyên tử. I E. Tôi có thể chắc chắn rằng khi một tài liệu được cập nhật, không có cập nhật nào khác sẽ ghi đè thay đổi trước đó của tôi. Câu hỏi của tôi liên quan đến sự kết hợp của câu truy vấn và câu lệnh cập nhật, và được minh họa tốt nhất bằng ví dụ dưới đây.Nguyên tử cập nhật của MongoDB có áp dụng cho cả truy vấn và sửa đổi không?

db.foo.update(
{ state : 1, players: { $size: 2 } } , 
{ $push: { players : { new player document } } }, 
false , true); 

Trong ví dụ trên, tôi chỉ muốn đẩy một cầu thủ mới vào một bộ sưu tập của các cầu thủ, nếu số lượng người chơi bằng 2. Với các truy vấn trên và báo cáo cập nhật, nó có thể là hai bản cập nhật đồng thời cả đẩy một người chơi lên cùng một tài liệu, vì tại thời điểm đọc tài liệu, người chơi của nó có kích thước $ là 2? I E. Liệu các atomicity span trên truy vấn và cập nhật một phần của báo cáo cập nhật hay không?

Sửa khác ở sâu chuỗi các sự kiện:

xem xét bắn cập nhật hai lần (U1 và U2) cùng một lúc. Chuỗi sự kiện sau đây có thể xảy ra hay không?

  1. U1 tìm thấy tài liệu # 1 khớp với phần truy vấn của bản cập nhật .
  2. U2 tìm thấy tài liệu # 1 khớp với phần truy vấn của tuyên bố cập nhật.
  3. U1 đẩy trình phát mới vào tài liệu số 1.
  4. U2 sẽ đẩy trình phát mới vào tài liệu số 1.

Kết quả cuối cùng là tài liệu # 1 chứa một trình phát nhiều hơn mong đợi, vì cả U1 và U2 đều có ấn tượng là tài liệu # 1 chỉ chứa hai người chơi.

Trả lời

3

Tôi đã hỏi câu hỏi này trên nhóm người dùng mongodb. http://groups.google.com/group/mongodb-user/browse_thread/thread/e61e220dc0f6f64c

Theo câu trả lời của Marc (người làm việc tại 10gen), tình huống mà tôi mô tả không thể xảy ra.

Tình huống mà bạn mô tả là không thể; không có nguy hiểm của cả hai bản cập nhật sửa đổi cùng một tài liệu.

0

Cập nhật: không chắc chắn về kiến ​​thức của tôi nữa ... Xem "The ABA Nuance". Xin vui lòng không chấp nhận câu trả lời này (hoặc bình luận của tôi dưới đây) vì nó có lẽ không chính xác. Rất muốn được sửa chữa.


Lối giải thích của nguyên tử là không chính xác (Tôi có thể chắc chắn rằng khi một tài liệu được cập nhật không có bản cập nhật khác sẽ ghi đè lên thay đổi trước đây của tôi). Các cập nhật khác có thể (và sẽ) ghi đè thay đổi của bạn. Nhưng họ sẽ không làm điều đó theo cách sẽ can thiệp vào tính toàn vẹn của truy vấn của bạn.

Điều quan trọng cần biết là bản cập nhật MongoDB là atomic on single document. Vì vậy, khi một tài liệu phù hợp với truy vấn của bạn, nó bị "khóa" và sẵn sàng cho một bản cập nhật. Lưu ý rằng bản cập nhật của bạn ($push) hoạt động bên trong cùng một tài liệu đã bị khóa. Khi cập nhật xong, khóa được giải phóng.

Tôi không chắc là tôi hiểu "không span số nguyên tử trên các truy vấn và cập nhật một phần của báo cáo cập nhật hay không", nhưng: phương tiện nguyên tử mà truy vấn khác không thể gây rối với truy vấn của chúng tôi. Truy vấn của chúng tôi có thể thay đổi dữ liệu bị "khóa".

Tuyên bố từ chối trách nhiệm: Tôi không bảo mật các cơ chế nội bộ MongoDB sử dụng để đảm bảo nguyên tử này, vì vậy mô tả này có thể thiếu quan điểm kỹ thuật (đặc biệt là kết nối với khóa) - nhưng hợp lệ. Đây là cách nó hoạt động từ quan điểm bên ngoài.

+0

Cảm ơn bạn đã trả lời. Tôi đã cập nhật câu hỏi của mình với một chuỗi sự kiện, điều mà tôi hy vọng làm rõ mọi thứ một chút. Bây giờ tôi nhận ra rằng những gì tôi hỏi về không phải là nguyên tử, mà là một giao dịch (khóa) ở cấp độ tài liệu. –

+0

Có, điều đó thực sự làm rõ câu hỏi. Bạn không có gì phải lo lắng. Không có gì có thể thay đổi tài liệu giữa tìm và cập nhật (bước 2 và 4) hoặc hoạt động sẽ không phải là nguyên tử. Nếu nó không hoạt động theo cách này, thì đó là một lỗi và nên được báo cáo như vậy. – johndodo

0

Với chuỗi sự kiện bạn viết xuống, bạn thực sự có thể có một người chơi quá nhiều.Bản cập nhật "tìm" và "cập nhật" hoạt động rất giống với việc thực hiện nó với "tìm" và sau đó là "cập nhật" trên từng tài liệu mà bạn đang lặp lại. Có thể bạn muốn xem nhà điều hành "$ nguyên tử": http://www.mongodb.org/display/DOCS/Atomic+Operations#AtomicOperations-ApplyingtoMultipleObjectsAtOnce

+1

Lưu ý rằng OP chỉ phát hành 2 bản cập nhật (U1 và U2), các bước chỉ ở đó để minh họa xung đột có thể xảy ra. – johndodo

Các vấn đề liên quan