【问题标题】:Transactional file writing in C# and Windows?用 C# 和 Windows 编写事务文件?
【发布时间】:2011-11-10 00:09:34
【问题描述】:

我有一个数据文件,有时我需要对文件进行更改。更改包括在多个地方更改信息。例如,更改文件末尾附近的一些数据以及更改文件开头附近的一些信息。我希望这两个单独的写入要么都成功,要么都失败,否则它会处于不确定状态并被有效地破坏。 .NET 或一般情况下是否对此方案有任何内置支持?

如果不是,那么其他人如何解决这个问题? Windows 上的数据库如何解决这个问题?

更新:我不想使用 Transactional NTFS 功能,因为它在旧版本的 Windows(例如 XP)上不可用,并且在上述文件覆盖方案中速度很慢。 p>

【问题讨论】:

  • 你要在什么文件系统上运行?
  • 查看事务性 NTFS 它指出文件中的覆盖性能非常慢。这是我的确切情况,因此作为一种方法看起来很慢。数据库如何在不使用 TxNTFS 的情况下管理相同的情况?
  • @PhilWright:数据库的工作原理是几乎整个 IT 历史上大量文献(书籍、学术论文……)的主题。远远超出了SO答案所能涵盖的范围。快速的网络搜索应该会找到一些介绍性内容(如果可以避免噪音)。维基百科应该让你started
  • 我同意 OP 的观点,即这个问题与链接的问题不重复。这里的这个问题比另一个问题更笼统,具体到 Windows 7。

标签: c# windows file transactions


【解决方案1】:

如果您使用的是 Windows 6 或更高版本 (Vista/7/2008/2008R2),NTFS 文件系统支持事务(包括在分布式事务中):但您需要使用 P/Invoke 来调用 Win32 API(请参阅此 @ 987654321@).

如果您需要在旧版本的 Windows 或非 NTFS 分区上运行,您需要自己执行事务。这绝对不是微不足道的:在处理跨进程和系统崩溃的多个进程(包括通过共享的远程访问)时获得完整的 ACID 功能,即使假设只使用您的访问方法(使用普通 Win32 API 的其他一些进程当然会打破东西)。

在这种情况下,数据库几乎肯定会更容易:有许多进程内数据库(SQL Compact Edition、SQL Lite...),因此数据库不需要服务器进程。

【讨论】:

  • 值得注意的是,微软正在考虑在未来的 Windows 版本中使用deprecating TxF
【解决方案2】:

DB 基本上使用 Journal 概念(至少我知道的那些)。一个想法是,在Writer 不提交事务之前,将写入操作写入日志。 (当然这只是基本描述,很简单)

在您的情况下,它可能是您的文件的副本,您将在其中写入数据,并且如果一切顺利完成,请用它的副本替换原始文件。

替换为:将原始文件重命名为old,将备份文件重命名为original

如果替换失败:这是一个严重错误,该应用程序应通过容错策略进行处理。可能是它通知用户保存操作失败,并尝试恢复。顺便说一句,您随时都有文件的两个副本。写操作刚开始时的那个,写操作完成时的那个。

我们在过去的 VS IDE 项目(如工业控制系统)中使用了这种技术,并取得了相当大的成功。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-31
  • 2012-04-13
  • 1970-01-01
  • 1970-01-01
  • 2014-12-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多