Tôi có nên khóa các hàng trong DB đám mây của mình trong khi chúng đang được người dùng chỉnh sửa


12

Tôi đang tạo một ứng dụng máy tính để bàn vẫn tồn tại dữ liệu trên đám mây. Một mối quan tâm tôi có là bắt đầu chỉnh sửa một mục trong ứng dụng và để nó trong một thời gian khiến dữ liệu trở nên cũ kỹ. Điều này rõ ràng cũng có thể xảy ra nếu 2 người cố gắng chỉnh sửa cùng một mục cùng một lúc. Khi họ hoàn thành chỉnh sửa và muốn lưu dữ liệu, tôi sẽ cần ghi đè lên những gì hiện có trong cơ sở dữ liệu hoặc kiểm tra xem họ đã bắt đầu chỉnh sửa sau thay đổi cuối cùng hay buộc họ loại bỏ các thay đổi của họ hoặc có thể cho họ tùy chọn để mạo hiểm ghi đè những thay đổi của người khác.

Tôi nghĩ về việc thêm một trường is_lockedlock_timestampvào bảng DB. Khi người dùng bắt đầu chỉnh sửa mục, hàng sẽ thay đổi is_lockedthành true và đặt dấu thời gian khóa thành thời gian hiện tại. Sau đó tôi sẽ có một khoảng thời gian mà khóa được giữ (ví dụ 5 phút). Nếu bất cứ ai khác cố gắng chỉnh sửa mục, họ sẽ nhận được một thông báo cho biết mục đó đã bị khóa và khi khóa tự động hết hạn. Nếu người dùng bỏ đi trong khi chỉnh sửa, khóa sẽ tự động hết hạn sau một khoảng thời gian tương đối ngắn và một khi người dùng sẽ được cảnh báo rằng khóa đã hết hạn và buộc phải khởi động lại chỉnh sửa sau khi dữ liệu được làm mới.

Đây sẽ là một phương pháp tốt để ngăn chặn ghi đè dữ liệu cũ? Có phải là quá mức không (tôi không hy vọng ứng dụng sẽ được sử dụng bởi nhiều người cùng lúc trên một tài khoản).

(Một mối quan tâm khác của tôi là có 2 người nhận được một khóa cho cùng một mặt hàng, tuy nhiên tôi tin rằng đó là một điều kiện cuộc đua mà tôi cảm thấy thoải mái.)


1
"Một mối quan tâm khác của tôi là có 2 người nhận được một khóa cho cùng một mặt hàng, tuy nhiên tôi tin rằng đó là một điều kiện cuộc đua mà tôi cảm thấy thoải mái" - sử dụng một giao dịch cơ sở dữ liệu xung quanh việc mua lại khóa sẽ ngăn chặn các điều kiện cuộc đua như vậy.
Jules

Hầu hết các công cụ cơ sở dữ liệu (ít nhất là loại quan hệ) đã được xây dựng để hỗ trợ cho việc này. Đó là một khái niệm rất phổ biến trong thế giới RDBMS và thậm chí các cơ sở dữ liệu "đồ chơi" cũng xử lý nó đủ tốt, với điều kiện bạn nói với bạn rằng bạn muốn khóa lạc quan hoặc bi quan. Dù sao, tôi không nghĩ rằng đó là thứ bạn cần để tự xây dựng bằng mọi cách: kiểm tra các tùy chọn trên công cụ db của bạn để xem cách làm việc với nó.
jleach

Thực tế là ứng dụng của bạn là một ứng dụng máy tính để bàn (một khách hàng béo ) không tạo ra nhiều khác biệt. Nó có thể được thiết kế theo cách tương tự như một ứng dụng máy chủ đa thể hiện có tính sẵn sàng cao.
Hosam Aly

Câu trả lời:


19

Một điều sẽ giúp bạn ở đây là thuật ngữ. Những gì bạn đang mô tả ở đây được gọi là 'khóa bi quan'. Thay thế chính cho phương pháp này là 'khóa lạc quan'. Trong khóa bi quan, mỗi diễn viên phải khóa bản ghi trước khi cập nhật và giải phóng khóa khi cập nhật hoàn tất. Trong khóa lạc quan, bạn cho rằng không ai khác đang cập nhật hồ sơ và thử. Bản cập nhật thất bại nếu bản ghi bị thay đổi bởi một số diễn viên khác.

Khóa tối ưu thường được ưa thích hơn nếu cơ hội hai diễn viên cập nhật cùng một thứ cùng một lúc là thấp. Bi quan thường được sử dụng khi cơ hội đó cao hoặc bạn cần biết bản cập nhật của bạn sẽ có thể thành công trước khi bắt đầu. Theo kinh nghiệm của tôi, khóa lạc quan hầu như luôn luôn thích hợp hơn bởi vì có nhiều vấn đề cố hữu trong khóa bi quan. Một trong những vấn đề lớn nhất được đưa ra trong câu hỏi của bạn. Người dùng có thể khóa một bản ghi để chỉnh sửa và sau đó rời đi để ăn trưa. Giảm nhẹ của bạn sẽ giúp với điều đó nhưng trải nghiệm người dùng sẽ không tốt hơn so với phương pháp lạc quan và có khả năng tồi tệ hơn nhiều. Ví dụ: một người dùng mở một bản ghi, bắt đầu cập nhật nó và ông chủ của họ xuất hiện tại bàn của họ. Một người dùng khác cố gắng chỉnh sửa hồ sơ. Nó bị khóa rồi. Người dùng thứ hai tiếp tục cố gắng và sau 5 phút, khóa hết hạn và người dùng thứ hai cập nhật hồ sơ. Người dùng đầu tiên quay lại màn hình, cố gắng lưu và được thông báo rằng họ bị mất khóa. Bây giờ trong cùng một kịch bản với mọi thứ giống nhau ngoại trừ sử dụng khóa tối ưu, trải nghiệm của người dùng đầu tiên khá giống nhau nhưng người dùng thứ hai không đợi 5 phút.

Lược đồ bạn đặt ra sẽ được cải thiện rất nhiều bằng cách thực hiện khóa tối ưu cho giá trị khóa nhưng linh cảm của tôi là khóa lạc quan có thể ổn cho toàn bộ và bạn có thể thoát khỏi trường is_locked.

Bạn không cung cấp 'DB đám mây' mà bạn đang sử dụng. Bạn có lẽ nên xem xét các tính năng của nó để xem liệu có các tính năng tích hợp cho việc này trước khi thực hiện giải pháp của riêng bạn không.

Đây là công thức cơ bản: thay vì trường is_locked, hãy có trường số phiên bản. Khi bạn truy xuất bản ghi, bạn kéo phiên bản hiện tại của bản ghi. Khi bạn cập nhật, bạn tạo bản cập nhật phụ thuộc vào trường phiên bản khớp với những gì bạn đã truy xuất và tăng nó thành công. Nếu phiên bản không khớp, bản cập nhật không có hiệu lực và bạn báo cáo lại là lỗi.


Đây là một câu trả lời rất hữu ích. Bạn có thể giải thích tại sao khóa bi quan không được khuyến khích khi có một cơ hội "va chạm" nhỏ. Có phải hoàn toàn là vì nó yêu cầu đến cơ sở dữ liệu để thậm chí bắt đầu chỉnh sửa, hoặc vì sự phức tạp thêm hoặc một số lý do khác? Cảm ơn!
yitzih

3
@yitzih Một số gợi ý đọc: Fowler et al, Các mô hình kiến ​​trúc ứng dụng doanh nghiệp . Có cả một chương về câu hỏi này, với thảo luận tốt về tất cả các lựa chọn và lý do để chọn chúng.
Jules

2
@Jimmy - Câu trả lời của bạn là tốt. Trong một số trường hợp, báo cáo lại lỗi của tôi là không đủ. Hãy xem xét một trường hợp khi người dùng dành vài phút để cập nhật một bản ghi. Trong trường hợp đó, chỉ cần thất bại có thể không đủ tốt, người ta có thể muốn cung cấp cho người dùng cơ hội để hợp nhất các thay đổi trên máy bay của họ với những thay đổi được cam kết bởi người dùng khác. Tôi nên nói rằng khóa lạc quan có thể yêu cầu giải quyết xung đột tùy thuộc vào yêu cầu của bạn.
Jon Raynor

3
Điều đáng nói là khóa bi quan dễ giải thích hơn với khách hàng. Nếu bạn viết một thông báo rằng máy khách không thể truy cập vào bản ghi vì nó hiện đang được chỉnh sửa bởi một người khác, thì cả máy khách đều hiểu tốt và thường chấp nhận nó. Thay vào đó, nếu bạn nói với khách hàng sau khi lưu thì không thể lưu bởi vì nó đã được cập nhật bởi một người dùng khác, 7/10, khách hàng sẽ thất vọng và / hoặc mong đợi những lời giải thích cho hành vi chương trình kỳ lạ này.
Neil

2
@Neil Điều đó đúng và tôi nghĩ rằng thường thì tại sao khóa bi quan lại được sử dụng khi lạc quan là phù hợp hơn. Thông thường quy trình làm việc khiến nó rất khó xảy ra va chạm.
JimmyJames

0

Từ câu trả lời của @ JimmyJames , chúng ta có thể thấy câu hỏi thực sự như thế nào về trải nghiệm người dùng .

Tất cả phụ thuộc vào bối cảnh. Mất bao nhiêu thời gian và công sức để cập nhật một bản ghi? Bao lâu thì nhiều người dùng muốn cập nhật cùng một tài liệu?

Ví dụ: nếu người dùng của bạn thường mất vài giây để cập nhật hồ sơ và có chút tranh cãi thì khóa lạc quan có lẽ là cách tốt nhất. Tệ nhất, người dùng sẽ phải mất thêm vài giây, có thể tới một phút để cập nhật tài liệu.

Nếu tài liệu của bạn gây tranh cãi cao nhưng có cấu trúc tốt, có thể bạn có thể cho phép họ khóa các trường riêng lẻ trong khoảng thời gian 30 giây, hiển thị đồng hồ bấm giờ hoặc thông báo không phô trương để cho phép họ mở rộng khóa.

Tuy nhiên, nếu người dùng của bạn dành một lượng thời gian hoặc nỗ lực đáng kể thì bạn nên xem xét các phương pháp khác. Hồ sơ của bạn có cấu trúc tốt? Bạn có thể hiển thị cho người dùng một so sánh (khác) giữa phiên bản trên máy chủ và phiên bản họ đang cố lưu không? Bạn có thể làm nổi bật sự khác biệt? Bạn có thể để họ hợp nhất các thay đổi? Hãy nghĩ về trải nghiệm bạn muốn có với các công cụ kiểm soát nguồn của bạn. Bạn thực sự không muốn bị buộc phải viết lại tất cả mã đó!

Bạn có thể nhìn vào Google Docs để có thêm cảm hứng. Có lẽ bạn có thể hiển thị cho người dùng một thông báo rằng một phiên bản mới đã được lưu. Có lẽ bạn có thể chỉ cho họ có bao nhiêu người mở hồ sơ để họ có thể chọn quay lại vào thời điểm ít tranh cãi hơn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.