在C#和Windows中编写事务性文件?

Phi*_*ght 12 c# windows transactions file

我有一个数据文件,有时我需要写一个文件的更改.变更包括在多个地方更改信息.例如,更改文件末尾附近的某些数据,并更改启动附近的某些信息.我希望两个单独的写入要么成功要么都失败,否则它将处于不确定状态并且实际上已损坏.在.NET或一般情况下,是否有针对此场景的内置支持?

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

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

Tig*_*ran 5

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

就您而言,它可能是文件的副本,您将在其中写入数据,如果一切顺利完成,则用其副本替换原始文件。

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

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

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


Ric*_*ard 4

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

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

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