簡體   English   中英

asp.net mvc; 僅為一個用戶一次編輯選項

[英]asp.net mvc; edit option only for one user at a time

我有一個表有三個記錄的字段。 如果用戶要從表中編輯記錄,則不允許其他用戶同時編輯該記錄。 我可以采取什么樣的步驟來實現這一目標?

來自桌面應用程序背景的很多人都會想知道如何在Web應用程序中完成此操作。

鎖定記錄標志

桌面世界中的一種方法是在行上有一個布爾列,表示正在編輯它,以及由誰編輯。 您當然可以使用Web應用程序執行此操作,但這是一種非常糟糕的方法,因為如果用戶訪問“編輯”頁面,將記錄置於鎖定狀態,然后離開頁面,它將永遠處於鎖定狀態。 您沒有明確的方法來告訴用戶仍然沒有打開編輯頁面。

時間敏感的鎖

航空公司預訂方法是上述的變體,但您也可以使用LockedUntilUtc,它是一個日期時間,表示記錄鎖定的時間。 假設Bob訪問了一個記錄頁面,當從GET操作提供apge時,您還設置了鎖定標志,並將LockedUntilUtc設置為10分鍾。 5分鍾后,Sarah訪問該頁面,但由於您檢查了LockedUntilUtc並且目前處於未來狀態,因此出現“當前已鎖定”錯誤。 再過6分鍾(自鎖定以來總共11分鍾)並且有人訪問該頁面並且LockedUntil現在已經過去,因此您將鎖定給新用戶。

這似乎是一個合理的妥協,但它充滿了肯定會讓用戶感到沮喪的問題。 首先,沒有簡單的方法來排隊需要訪問權限的用戶來編輯記錄。 Sarah可以嘗試10次,然后就在它經過10分鍾時,Jimmy訪問了該頁面,因為他是鎖定過期后的第一個人,他抓住了下一個鎖定而Sarah沒有機會。 Sarah打電話給你的服務台,說她等了10分鍾才能鎖定到期,現在已經15分鍾,她仍然無法進入該頁面。 你的服務台可能會懷疑她真的等了整整10分鍾,然后來回。

您還必須為當前擁有鎖定的人實施客戶端計時器/顯示器,以便他們知道在它到期之前還剩多少時間。

樂觀並發

在大多數情況下,這是正確的方法。 實際上你根本沒有以任何方式鎖定記錄。 相反,許多用戶可以訪問編輯頁面。 當他們保存編輯時,表單包括原始值和新編輯的值。 服務器將比較表單中的原始值與數據庫中的當前值,以查看是否存在臨時編輯。

原始值來自過去的某個時刻(當Bob最初訪問編輯頁面時)。 目前的價值來自現在。 在過去和現在之間,如果Sarah也訪問了編輯頁面,並成功保存了對數據庫值的更改,那么Bob的原始值將與數據庫中的當前值不同。 因此,當Bob嘗試保存其更改時,服務器將看到其原始值與DB中的當前值不同,並拋出錯誤。 您需要決定如何處理這種情況。 通常,您讓用戶知道其他人已經編輯過頁面,並刷新頁面,然后他們就會丟失編輯內容。 實體框架支持樂觀並發。

Ajax'ified樂觀並發

您還可以讓客戶端偶爾使用原始值ping服務器,以便服務器可以檢查您的頁面是否過時(即其他用戶更改了某些內容)並彈出消息。 這通過向用戶提前通知另一用戶已編輯頁面來改善用戶體驗。 因此,他們在進行編輯方面並沒有走得太遠,反正他們將會失敗。 他們還可以從瀏覽器中記錄/復制/粘貼他們的編輯內容,以便刷新頁面並參考他們更改的內容。

SQL Server中有一個Timestamp列,它可以與Entity Framework協同工作,以降低檢查更改所涉及的開銷。 這樣您就不需要在每個客戶端中保留原始值的整個記錄​​並將其傳回來: http//www.remondo.net/entity-framework-concurrency-checking-with-timestamp/

細粒度編輯

我們使用的一種方法是ajax'ify每個字段,並立即提交到單個字段的編輯。 這是使用名為x-editable的jquery庫完成的。 用戶編輯單個字段,確認編輯,並將該值發送到服務器。 如果要檢查整個記錄的更改,或者只檢查單個字段,可以將其與樂觀並發相結合。 如果檢測到更改,則拒絕編輯並刷新頁面。 這對於用戶來說可以是更友好的體驗,主要是因為用戶在編輯單個字段時立即獲得“另一個用戶編輯的頁面”錯誤。 這可以防止他們浪費大量時間來編輯大量字段,但卻發現他們的編輯遭到拒絕,他們不得不重新編輯所有編輯內容 相反,他們編輯單個字段,獲取錯誤,頁面刷新, 他們只需要重復那一個字段編輯並從那里繼續

http://vitalets.github.io/x-editable/demo-bs3.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM