我在PHP中做了一個web服務,它根據表中的選擇進行一系列計算,然後用新結果更新表。PHP中的MySql表鎖定
但是,我想阻止另一個人正在對另一個人的會話進行更新時調用同一個Web服務的情況。
在這裏鎖定整個表然後再解鎖它是正確的嗎?如果是這樣,我如何鎖定和解鎖使用PHP pdo的MySQL表?
我在PHP中做了一個web服務,它根據表中的選擇進行一系列計算,然後用新結果更新表。PHP中的MySql表鎖定
但是,我想阻止另一個人正在對另一個人的會話進行更新時調用同一個Web服務的情況。
在這裏鎖定整個表然後再解鎖它是正確的嗎?如果是這樣,我如何鎖定和解鎖使用PHP pdo的MySQL表?
我發佈的評論:
不是一個直接的答案,但我不認爲這是什麼問題。計算和從數據庫獲取數據在幾個012毫秒內完成。一次或兩個人在同一時間進行互動的機會太小,以至於大多數人不會打擾這樣做。
但如果這些計算是至關重要的,你可以通過添加一個新的領域防止這個問題,簡單地稱之爲occupied
,busy
或類似的東西。
當您運行腳本時,檢查該字段是否設置爲例如1,如果是,則使腳本睡眠1-2-3秒,然後重試。如果此字段設置爲0,則將其更新爲1,執行計算並將其重新設置爲0。
這會阻止兩個人同時訪問相同的值。
此方法的問題在於,如果兩個客戶端在更新之前都讀取檢查字段的值,他們都會認爲他們可以繼續。爲了確保併發應用程序的安全,需要CPU自動執行操作*:操作系統爲此提供了一個API,而RDBMS則調用該API來實現其鎖定機制。 **不要試圖自己建立**,因爲它註定要失敗。相反,使用數據庫事務提供的原子性:這就是他們在那裏。 – eggyal
這似乎是最安全的實施解決方案,我願意走這條路。是否有任何可能的解決方案來防止案件提及? – user1574041
@eggyal:閱讀發佈在這裏的其他答案。兩個人不可能在同一時間訪問它。發生這種情況太快了。 – OptimusCrime
像MySQL這樣的數據庫管理系統足夠聰明,可以防止像這樣的併發衝突。
查找數據庫隔離級別(讀取未提交,讀取提交,可重複讀取,可序列化)和可能出現的問題(髒讀,不可重複讀取...) - >Wikipedia。
就我個人而言,我不會在你的情況下推薦一個表鎖。你最好在交易中包裹你的計算和數據庫操作,並依靠DBMS來管理你的東西。
但是我現在這樣做: 1)在我的表格上做一個選擇 2)根據我的選擇在PHP中進行計算 3)根據PHP計算更新表格。 交易中可能嗎?我對數據庫比較陌生。 – user1574041
@ user1574041:您可以使用[鎖定讀取](http://dev.mysql.com/doc/en/innodb-locking-reads.html),如「SELECT ... FOR UPDATE」。但是,您也可能會發現,您可以將計算邏輯從PHP轉移到SQL中,以便在單個「UPDATE」語句中執行,例如'UPDATE myTable SET myColumn =(1 + myColumn)* 2 WHERE ...'。 – eggyal
謝謝@eggyal,也是我的建議。如果您決定必須在php中進行計算並且不想鎖定整個表格,則可能需要查看像'flock'這樣的文件庫鎖定機制:http://php.net/manual/en/ function.flock.php –
不是一個直接的答案,但我不認爲這是任何問題。從數據庫中計算和提取數據在幾毫秒內完成。在同一時間互動的機會或者兩個人太小,大多數人不會打擾這樣做。 – OptimusCrime
我確實意識到這一點。但是我不願意承擔風險,因爲數據腐敗可能會對我的申請造成重大後果。 – user1574041
您想使用[數據庫事務](http://dev.mysql.com/doc/en/sql-syntax-transactions.html),以確保操作的原子性。 – eggyal