无论文件是通过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