9

我正在做一个在线文件管理项目。我们将引用存储在数据库(sql server)上,并将文件数据存储在文件系统上。

在上传文件以及删除文件时,我们面临着文件系统和数据库之间的协调问题。首先,我们在数据库中创建一个引用或将文件存储在文件系统上。

问题是,如果我先在数据库中创建引用,然后在文件系统上存储文件,但在文件系统上存储文件时发生任何类型的错误,则在数据库中创建该文件的引用但没有文件数据存在于文件系统中。

请给我一些解决方案如何处理这种情况。我非常需要它。

当我们删除文件时也会发生这种情况?

4

4 回答 4

6

对文件系统的访问确实不是事务性的。您将需要自己模拟一个全有或全无的分布式事务:如果数据库中的提交失败,则删除文件系统上的文件。相反,如果写入文件失败,则回滚数据库事务(这会有点复杂,但这是一个粗略的草图)。

请注意,更新文件时可能会变得非常复杂。您需要先复制它,这样如果在覆盖文件后数据库事务失败,您仍然可以恢复旧版本的文件。是否要执行此操作取决于所需的稳健性级别。

尝试强制所有操作都通过您的应用程序(创建、写入、删除文件)。如果你不能这样做并且你不能阻止直接在文件系统上访问文件(并且可能被删除),我认为除了定期将数据库与文件系统同步之外别无他法:检查哪个文件被删除并删除数据库中的条目。您可以为此创建一个每X分钟运行一次的作业。

我还建议在数据库中存储文件的哈希值(例如 MD5)。花一些时间来计算它,但这对我检测问题非常有用,例如,如果文件在文件系统上被错误重命名但不在数据库中。这也允许定期运行一些完整性检查,以验证没有任何问题。

如果这种方法还不够(例如,您希望它更健壮),我认为除了将二进制文件存储在 LOB 中的数据库中之外别无他法。然后它将是真正的交易和安全的。

于 2010-03-26T16:37:04.310 回答
1

我知道一个老问题,但为了其他读者的利益:

根据您的操作系统,您可能可以使用事务性 TxF

http://msdn.microsoft.com/en-us/magazine/cc163388.aspx

于 2011-06-13T01:41:33.610 回答
0

将这两个事件(管理引用和管理文件)视为单个事务。如果其中一个失败,则将另一个退出。然后你会发现很难进入两者不同步的情况。回滚数据库操作比文件系统操作更容易。

于 2010-03-26T16:31:40.447 回答
0

SQL Server 2008 中引入了FILESTREAM来解决这个确切的问题。

然而,它也有自己的一套实施挑战

于 2014-04-18T16:41:13.890 回答