【问题标题】:Atomic modification of files across multiple networks跨多个网络的文件的原子修改
【发布时间】:2009-05-11 15:06:19
【问题描述】:

我有一个应用程序正在修改 5 个相同的 xml 文件,每个文件位于不同的网络共享上。我知道这是不必要的多余,但“必须如此。”

每次运行此应用程序时,都会添加/删除/修改一个元素(不多也不少)。

最初,应用程序会打开每个 xml 文件,将元素添加/删除/修改到相应的节点并保存文件,如果不能,则抛出错误(无法访问网络共享、超时等...)

如何使这个原子化?

我最初的假设是:

foreach (var path in NetworkPaths)
    if (!File.Exists(path)
        isAtomic = false;

if (isAtomic)
{
    //Do things
}

但我只能看到到目前为止。有没有其他方法可以做到这一点,或者我可以指出一个方向?

【问题讨论】:

    标签: c# file atomic


    【解决方案1】:

    不幸的是,真正的“原子”是不可能的。我最好的建议是为此打包您自己的交易形式,这样您至少可以撤消更改。

    我会检查每个文件 - 如果不存在,则抛出。

    备份每个文件,保存撤消所需的状态,或者如果它们不是很大,则在内存中保存一份副本。做不到就扔。

    进行编辑,然后保存文件。如果您在此处遇到故障,请尝试从每个备份中恢复。您需要在此处进行一些错误处理,以便在恢复所有备份之前不要抛出异常。恢复后,抛出异常。

    至少通过这种方式,您更有可能不会只对单个文件进行更改。希望如果您可以修改一个文件,您将能够从备份中恢复它/撤消您的修改。

    【讨论】:

      【解决方案2】:

      我建议以下解决方案。

      • 尝试使用写锁打开所有文件。
        • 如果一个或多个失败,则中止。
        • 修改并刷新所有文件。
          • 如果有一个或多个失败,请将已修改的回滚并再次刷新。
      • 关闭所有文件。

      如果回滚失败......好吧......再试一次,再试一次,再试一次......然后在不一致的状态下放弃。

      如果您可以控制所有写入此文件的进程,则可以使用锁定文件实现简单的锁定机制。您甚至可以执行预写日志记录并在锁定文件中记录计划的更改。如果您的进程崩溃,下一个尝试修改文件的进程会检测到不完整的操作,并且可以在进行一次修改之前继续它。

      【讨论】:

        【解决方案3】:

        我将介绍文件的版本控制。您可以通过将后缀附加到文件名来轻松完成此操作。例如计数器变量。读者流程如下:

        • 准备下一个版本的文件
        • 将其写入具有不同名称的临时文件。
        • 获取最高版本号
        • 将此版本加一
        • 将临时文件重命名为新文件
        • 删除旧文件(您可以保留例如其中的 2 个)

        作为读者你做 - 找到最高版本的文件 - 阅读它

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-06-12
          • 2020-06-27
          • 2011-12-30
          • 1970-01-01
          • 2016-04-28
          相关资源
          最近更新 更多