我們正在構建一個ajax應用程序。我們希望有幾個用戶可以同時訪問該應用程序。因此,我有這樣的想法:以一種方式運行每個更新查詢,以便它們提供以前的字段值。問題是,如果以前的值不是系統預期的那麼PostgreSQL應該拋出一個錯誤(也就是說有人在我們的用戶被賦予值後修改了它)。在一個事務和數據庫級別處理這個問題是很好用的,因爲沒有併發問題。這可能嗎?處理數據庫中的AJAX併發問題
回答
因此,我有一個辦法運行的每一個更新查詢的想法,讓他們提供字段的前值
你所描述稱爲「樂觀併發控制」或一招「樂觀鎖定「。它已經建立並已被證實。
參見:
- http://en.wikipedia.org/wiki/Optimistic_concurrency_control
- http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/transactions.html#transactions-optimistic(Hibernate中,一個Java ORM,但原則適用於許多系統)
即使ODBC早在今年點這樣做,雖然ODBC使用的原始方法有一些問題。
擁有一個專用修訂列通常要好得多,它應該是一個隨每次更新而遞增的整數。不要使用時間戳。
你可以這樣做:
SELECT col1, version FROM sometable WHERE id = 42;
想象你得到的結果行('bob',7)
你然後運行:
UPDATE sometable SET col1 = 'fred' WHERE id = 42 AND version = 7;
,並檢查有多少行受到了影響。如果它爲零,則知道存在更新衝突。
如果您在同一數據庫中混合使用樂觀鎖定和常規應用程序,則可以使用a trigger to make sure the optimistic locking column always gets incremented,以便您的常規應用程序和操作鎖定應用程序可以良好地協同工作。
這種策略不能在PostgreSQL的觸發分區表上工作。
如果你想在數據庫中這樣做,我想你將不得不在表上使用觸發器。在觸發器中,您可以根據「新」(您發送的更新內容)來檢查「舊」(表中的內容)。我不認爲你可以使用這個規則。您也可以使用表中最後一次修改的列,而不是傳遞和比較所有列。
CREATE TRIGGER check_update
BEFORE UPDATE ON table
FOR EACH ROW
WHEN (OLD.timestamp IS DISTINCT FROM NEW.timestamp)
EXECUTE PROCEDURE check_update();
如果您不想使用時間戳,則可以在WHEN子句中包含所有列檢查。然後您可以讓check_update()過程執行某些操作,也許會引發異常或返回現在存在的數據。可能有更好的方法,但這應該起作用。
postgreSQL MVCC模型可以確保在用戶事務讀取並保存數據更改時,沒有人正在更改數據。這將特別通過使用serializable transaction level ... 但是來執行。
你真正的問題不在於保存階段,在這個階段很容易打開一個事務,讀取數據,修改它並提交這個事務;你的問題是網絡問題。 您無法打開一個事務,讀取數據,通過您的Web應用程序將其推送給最終用戶,然後等待幾秒/分鐘的時間用於ajax請求,然後保存更改的數據並提交。交易不會長時間保持開放狀態,並會在用戶發佈後恢復。
因此,在Web應用程序服務器端,您擁有的是表單文章,並且您想要保存更改的數據。您特別想要檢測在用戶加載頁面,進行某些操作並決定按下提交按鈕之間會發生變化的數據。一種方法是在用戶信息中存儲原始未改變數據的副本,並將此數據與當前存儲數據進行比較。另一種方法是使用@Scott S的解決方案(最後一個修改時間戳)來標記數據庫中的數據記錄。並在每次修改後重新計算(可能使用觸發器)。然後,將這些(或這些)數據簽名嵌入到用戶表單中,並在打開保存事務之後,首先要做的就是比較md5sum,並在數據似乎已被更改的情況下回滾整個操作。因爲數據庫將僅管理異步數據操作(事務隔離管理和鎖定)而不是長期用戶共享數據策略,這不是數據庫角色,而是應用程序邏輯。您的應用程序必須通過異步窗體lobd和posts來處理共享策略。例如參見維基百科處理它的方式。如果您在編輯模式下從多個位置加載相同的頁面並嘗試同時保存,則會檢測到之前的修改並且您的第二次保存被拒絕。對於絕大多數Web應用程序igores來說,這是個棘手的問題,最後的提交也是贏得的。
UPDATE
要使用同步修改的AJAX管理走得更遠,你可以建立一個相當複雜的系統,用LISTEN和NOTIFY SQL關鍵字檢測修改和推背論文在客戶端事情。如果您的應用程序服務器是持久性的(不像PHP或jsp),並且如果您使用與comet或其他push technology等系統一起使用持久性ajax連接仿真,那麼當另一個用戶進行事務提交改變了某些數據以他的形式顯示。這不會消除用戶在非常近的時間提交修改的問題(並行用戶請求處理服務器端)。對於最後一種情況,唯一的解決方案是使用一個很好的交易,也許在可序列化的槓桿中,並且總是管理用戶修改可能被拒絕的事實服務器端(這是交易的關鍵,總是管理交易可以即使您沒有犯錯誤,也僅僅因爲修改與並行提交事務衝突而被服務器回滾)。
- 1. 處理數據庫級別的併發問題
- 2. 處理Liferay Cluster中的併發問題
- 3. 如何處理股市應用程序中數據庫的併發問題?
- 4. 如何處理數據庫併發
- 5. 如何處理連接數據庫時發生的問題?
- 6. php ajax數據庫問題
- 7. AJAX數據庫問題
- 8. Azure數據庫併發使用問題
- 9. 數據庫併發性問題
- 10. 如何處理這個數據併發問題?
- 11. JSON數據處理問題
- 12. Ajax處理 - 安全問題
- 13. AWK處理數據中的%問題
- 14. Neo4j/REST批處理併發問題
- 15. PHP處理併發性問題
- 16. mysql數據庫中的併發訪問問題
- 17. 如何處理數據庫中的併發更新?
- 18. 在Rails數據庫中處理併發請求的唯一性
- 19. CodeIngniter中的數據庫錯誤處理問題
- 20. ajax調用服務器端處理數據表的問題
- 21. 併發問題通過AJAX
- 22. 數據庫開發問題
- 23. 在oracle數據庫中處理併發請求?
- 24. 如何在MySQL數據庫中處理併發查詢?
- 25. 發送數據的PHP和AJAX問題
- 26. JQuery的Ajax WCF:問題發佈數據
- 27. 使用$ .ajax發送數據的問題
- 28. 併發處理的Ajax請求
- 29. 如何使AJAX請求發佈JSON數據並處理響應
- 30. 在symfony批處理腳本中訪問數據庫併發送電子郵件
使用'LISTEN'和'NOTIFY'來提醒用戶衝突是很有用的。其餘的方式過於複雜,但;只需使用修訂版計數器列即可,它很簡單,可靠且易於執行。 –
@Craig Ringer:如果你只是在兩個並行事務中增加它,甚至修改計數器可能會被嚴重管理,所以在大多數事務模式下,你應該讀/檢查事務中的版本,並確保正確的行鎖定和/或事務中止。 – regilero