CouchDB sử dụng mô hình "đồng thời lạc quan". Nói một cách đơn giản nhất, điều này chỉ có nghĩa là bạn gửi một phiên bản tài liệu cùng với bản cập nhật của mình và CouchDB từ chối thay đổi nếu phiên bản tài liệu hiện tại không khớp với những gì bạn đã gửi.
Nó thực sự đơn giản. Bạn có thể điều chỉnh lại nhiều tình huống dựa trên giao dịch thông thường cho CouchDB. Tuy nhiên, bạn cần phải loại bỏ kiến thức miền RDBMS của mình khi học CouchDB. Sẽ hữu ích khi tiếp cận các vấn đề từ cấp độ cao hơn, thay vì cố gắng đưa Couch vào thế giới dựa trên SQL.
Theo dõi hàng tồn kho
Vấn đề bạn nêu ra chủ yếu là vấn đề hàng tồn kho. Nếu bạn có tài liệu mô tả một mặt hàng và nó bao gồm trường "số lượng có sẵn", bạn có thể xử lý các vấn đề đồng thời như sau:
- Lấy tài liệu, ghi lại
_rev
tài sản mà CouchDB gửi cùng
- Giảm trường số lượng, nếu nó lớn hơn 0
- Gửi lại tài liệu đã cập nhật, sử dụng thuộc
_rev
tính
- Nếu
_rev
kết quả khớp với số hiện đang được lưu trữ, hãy hoàn tất!
- Nếu có xung đột (khi
_rev
không khớp), hãy truy xuất phiên bản tài liệu mới nhất
Trong trường hợp này, có hai trường hợp thất bại có thể xảy ra. Nếu phiên bản tài liệu gần đây nhất có số lượng bằng 0, bạn xử lý nó giống như bạn làm trong RDBMS và cảnh báo cho người dùng rằng họ thực sự không thể mua thứ họ muốn mua. Nếu phiên bản tài liệu gần đây nhất có số lượng lớn hơn 0, bạn chỉ cần lặp lại thao tác với dữ liệu đã cập nhật và bắt đầu lại từ đầu. Điều này buộc bạn phải thực hiện nhiều công việc hơn một chút so với RDBMS và có thể gây khó chịu một chút nếu có các bản cập nhật thường xuyên, xung đột.
Bây giờ, câu trả lời tôi chỉ đưa ra giả định rằng bạn sẽ làm mọi thứ trong CouchDB giống như cách bạn làm trong RDBMS. Tôi có thể tiếp cận vấn đề này hơi khác một chút:
Tôi sẽ bắt đầu với tài liệu "sản phẩm chính" bao gồm tất cả dữ liệu mô tả (tên, hình ảnh, mô tả, giá, v.v.). Sau đó, tôi sẽ thêm tài liệu "phiếu kiểm kê" cho từng trường hợp cụ thể, với các trường cho product_key
và claimed_by
. Nếu bạn đang bán một mô hình búa, và có 20 trong số họ để bán, bạn có thể có văn bản với các phím như hammer-1
, hammer-2
, vv, để đại diện cho mỗi búa sẵn.
Sau đó, tôi sẽ tạo một dạng xem cung cấp cho tôi danh sách các búa có sẵn, với chức năng giảm cho phép tôi xem "tổng số". Những thứ này hoàn toàn không nằm ngoài vòng bít, nhưng sẽ cung cấp cho bạn ý tưởng về chế độ xem làm việc sẽ như thế nào.
Bản đồ
function(doc)
{
if (doc.type == 'inventory_ticket' && doc.claimed_by == null ) {
emit(doc.product_key, { 'inventory_ticket' :doc.id, '_rev' : doc._rev });
}
}
Điều này cung cấp cho tôi danh sách các "vé" có sẵn, theo khóa sản phẩm. Tôi có thể lấy một nhóm trong số này khi ai đó muốn mua một cái búa, sau đó lặp lại thông qua việc gửi cập nhật (sử dụng id
và _rev
) cho đến khi tôi yêu cầu thành công một (các vé đã yêu cầu trước đó sẽ dẫn đến lỗi cập nhật).
Giảm
function (keys, values, combine) {
return values.length;
}
Hàm giảm này chỉ đơn giản trả về tổng số inventory_ticket
mặt hàng chưa có người nhận , vì vậy bạn có thể cho biết có bao nhiêu "búa" để mua.
Cảnh báo
Giải pháp này thể hiện tổng số khoảng 3,5 phút suy nghĩ cho vấn đề cụ thể mà bạn đã trình bày. Có thể có nhiều cách tốt hơn để làm điều này! Điều đó nói rằng, nó làm giảm đáng kể các cập nhật xung đột và giảm nhu cầu phản hồi xung đột với một bản cập nhật mới. Theo mô hình này, bạn sẽ không có nhiều người dùng cố gắng thay đổi dữ liệu trong mục nhập sản phẩm chính. Trong trường hợp tồi tệ nhất, bạn sẽ có nhiều người dùng cố gắng yêu cầu một vé duy nhất và nếu bạn đã lấy được một số người trong số họ từ chế độ xem của mình, bạn chỉ cần chuyển sang vé tiếp theo và thử lại.
Tham khảo: https://wiki.apache.org/couchdb/Frequently_asked_questions#How_do_I_use_transactions_with_CouchDB.3F