gpt4 book ai didi

database-design - 如何保证跨两个数据库(文件系统和 RDBMS)的原子性?

转载 作者:行者123 更新时间:2023-12-01 05:45:40 24 4
gpt4 key购买 nike

我正在做一个在线文件管理项目。我们在其中存储对数据库(sql server)的引用和在文件系统上的文件数据;在其中我们面临着文件系统和数据库之间的协调问题,而我们正在上传文件以及删除文件的情况下,首先我们在数据库中创建引用或将文件存储在文件系统中;问题是,如果先在数据库中创建引用,然后将文件存储在文件系统中。 bur 在文件系统上存储文件时发生任何类型的错误。然后在数据库中创建该文件的引用,但文件系统上没有文件数据;;请给我一些如何处理这种情况的解决方案;;我非常需要它;;
原因是什么?

最佳答案

这实际上比您想象的要容易一些。

首先,您需要确定“单一事实来源”。

也就是说,文件系统或数据库在任何给定的时间点都是正确的,它是哪一个?

这样做的原因是它可以更容易地解决冲突。

您应该假设数据库是您的源,并且文件系统是数据库的影子。这似乎违反直觉,因为如果一个条目不在文件系统中,它怎么会存在于数据库中。显然不能。但是,基本上,如果文件不在数据库中,那么无论如何“它不存在”。因此,文件系统反射(reflect)了数据库的状态,而不是相反。

鉴于这些假设,您最终会得到这些冲突解决规则。

对于任何给定的文件:

File Exists    DB Entry Exists   Action
Yes Yes No action, normal state
No Yes Error -- missing file, "should never happen"
No No No action, normal state
Yes No Delete the file, but no error.

上传文件时,存在一个灰色区域——即当文件上传但尚未被数据库确认时。

解决此问题的方法需要以暂存模式上传文件。

一种简单的方法是将文件上传到不同的目录,但在同一物理文件系统上,或者使用临时文件名将其上传到最终位置。无论哪种方式,该文件都可以通过其名称或位置轻松识别为“正在处理”。

出于两个原因,您希望将此文件“暂存”在同一文件系统上。一,磁盘空间。如果上传时磁盘没有填满,那么您就知道它将适合它的最终放置位置(它已经“保留”了空间)。二,当您最终放置文件时,该操作必须是原子的。同一文件系统上的文件重命名操作在现代文件系统上是原子的。基本上,您不能让文件“重命名一半”,即使它不可避免地“覆盖”了现有文件(原始文件在重命名操作期间被删除)。

一旦上演,您的操作将变为:
Start DB transaction
Rename file
Add DB record
Commit transaction

如果重命名文件操作失败,您将中止并回滚数据库事务,从而回滚条目。如果重命名成功,而数据库失败?然后你有上面列出的状态#4。重试上传直到成功。

要删除文件,请执行以下操作:
Start DB Transaction
Delete DB record
Commit transaction
Delete file from file system

如果数据库删除失败,则不会删除该文件。如果数据库删除成功,文件删除失败,那么我们回到状态#4。

最后,您有一个 reaper 进程,它定期(每天、每周等等)将数据库与文件系统进行比较,删除任何不在数据库中的文件。由于 DB 是“单一事实来源”,这两个存储最终会同步。

如果丢失了具有 DB 记录的文件,那么您就有了“数据损坏”。不要那样做。这是一个错误,或者有人正在检查您的文件系统。

上传过程的重试特性和删除过程的快速失败为您提供了一个伪两阶段提交过程,易于检查对错,并易于纠正到正确的状态。

关于database-design - 如何保证跨两个数据库(文件系统和 RDBMS)的原子性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2525821/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com