2011-06-12 34 views
1

我正在開發一個相對簡單的自定義Web應用程序,並在後端安裝了MySQL MyISAM數據庫。不知何故,我想避免經典的併發覆蓋問題,例如該用戶A覆蓋用戶B的編輯,因爲B在A完成之前加載並提交了一些編輯表單。我應該使用MySQL的自定義'鎖'表嗎?

這就是爲什麼我想以某種方式鎖定顯示編輯表單的行。然而...

  • 正如我所說,我使用的MyISAM,據我所知,它不支持行級鎖。另外,我不確定是否持有「真正的」MySQL鎖定幾分鐘是建議的做法。
  • 我對交易並不十分了解,但從我所看到的看來,它們看起來像是在一個連接中使用。
  • 使用像Git這樣的衝突合併系統真的不是一個選項。

行將保持鎖定幾分鐘。併發性非常低:有六位用戶隨時使用該應用程序。

我現在正在計劃使用一張表,詳細介紹哪些用戶正在做什麼以及從何時開始。當其他用戶最近打開它時(例如正在處理它),應用程序可以決定不顯示編輯表單。在保存表格時,這個假鎖將被刪除。

會這樣嗎?我應該怎麼做才能避免死鎖,活鎖和所有這些東西?

回答

3

您可以實現一個鎖,最簡單的可能是將兩個字段添加到要鎖定的數據(lock_created Datetime,locked_by int)。然後在編輯頁面(也可能在編輯按鈕上),你現在檢查(lock_created + lock_interval)<() - 如果沒有,數據被鎖定進行編輯,應該通知用戶。 (請注意,您始終需要在編輯頁面上進行檢查,而不僅僅是編輯按鈕。) 同樣在提交頁面上,您需要檢查用戶是否仍然有要提交的鎖定。 (見下面)

這個難題之一是當有人編輯但在鎖定間隔內未能提交時該怎麼做。 So:

  1. lock_interval是2分鐘。
  2. 在時間0:00 Alice鎖定頁面,編輯某些內容,但接到電話並且未提交她的更改
  3. 在時間2:30 Bob檢查頁面,獲取編輯鎖,因爲Alice的鎖已過期,並編輯
  4. 在3點時,愛麗絲回到她的比賽,按提交 - >衝突。

有人沒有提交他們的數據。如果將鎖設置爲過期,則無法解決此問題。 (如果你不這樣做,鎖可以永遠留下。) 您只能決定優先考慮哪一個(使用由Bob創建的新鎖可能是最簡單的),並通知對方頁面已過期,數據將不被合併,並將它們的編輯交給他們以重做它們。

關於表結構的說明:您可以創建一個表'locks',其中包含字段'table_name,row_id,lock_created,locked_by',但它可能不是最簡單的方法,因爲加入變量表名是複雜的混亂。此外,有可能沒有用於存儲所有鎖的單個地方。對於一個簡單的機制,我認爲爲每個要實現鎖定機制的表添加統一字段更容易。

+0

感謝您的明確答案!我想我會用相當短的到期時間,並用AJAX以某種方式刷新它們。 – 2011-06-13 07:17:59

0

在這種情況下,您絕對不應該使用行級鎖。

您可以使用樂觀鎖定,這基本上意味着每個行都有一個版本字段,當行被保存時,版本字段會增加。在保存之前,請確保版本字段與加載該行時的版本字段相同,這意味着自從您讀取該行後沒有其他人保存任何內容。

+0

但是,你會怎樣處理'最新'版本,即否則會覆蓋'半新'版本?如果此行由其他人編輯,那麼失敗將意味着用戶的某個更改會丟失。 – 2011-06-12 12:06:40

相關問題