無論文件是通過UPDATE還是刪除行從數據庫中「刪除」,問題都是一樣的 - 數據庫+文件操作不是原子操作。 UPDATE或DELETE都比另一個更安全,它們都是數據庫中的事務,而文件操作不是。
解決方案是從來沒有任何衝突的數據狀態。只有一個來源被認爲是「真相」,另一個來源則反映了這個真相。這樣,如果兩者之間存在矛盾,你就知道「真相」是什麼。事實上,永遠不會有「邏輯」的不一致性,只有磁盤上的物理文物纔會表現出善後。
在大多數情況下,數據庫是The Truth的更好表示。
這裏的真值表:
File Exists -- DB Record exists -- Truth
Yes No File does not exist
Yes Yes File does exist
No Yes File does exist, but its in error.
No No File does not exist
操作上,這裏是如何工作的。
要創建文件,請將文件複製到最終目的地,然後在數據庫中輸入條目。
如果文件複製失敗,則不更新數據庫。 如果文件複製成功,但數據庫未更新,則文件「不存在」,因此回到第一步。 如果文件複製成功並且數據庫更新成功,則所有內容均爲A-確定
要刪除文件,首先更新數據庫以顯示文件被刪除。 如果數據庫更新成功,則刪除實際的文件。 如果數據庫更新沒有,則不要刪除該文件。 如果文件刪除失敗,沒有問題 - 文件仍然被「刪除」,因爲數據庫是這樣說的。
如果您按照工作流程進行操作,那麼在數據庫表示它存在時文件應該丟失是「無法」的。如果文件丟失,您有未定義的狀態,您需要解決。但是這不應該發生,除非有人在你的文件系統上行走。
數據庫事務有助於保持誠實。
有時候,正如Jonathan所說,你應該運行某種清理,同步過程以確保沒有任何流氓文件。但即使如此,除了文件空間,這實際上不是問題,特別是如果實際文件的文件名與原始文件名無關。 (即他們是合成文件名)這樣你就不必擔心覆蓋等。
文件名是從表中的主鍵生成的,專門用於防止衝突。感謝真相表 - 它讓我從不同角度考慮問題總是有幫助的。 – robinjam 2010-06-24 06:38:35
順便說一下,我認爲MySQL保證單個操作(如UPDATE和DELETE)的事務安全性,即它可以工作或返回錯誤。我錯了嗎? – robinjam 2010-06-24 06:43:00
不,你是對的。這就是如何工作的原因,因爲你總是「知道」數據庫的狀態(因爲即使失敗它也會回滾),所以它是一個更可靠的「真相源」。我只是指出更新和刪除之間沒有區別 - 它們作爲記錄文件狀態的手段同樣安全,而且由於數據庫的事務性質,這也是如此。 – 2010-06-24 14:22:31