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

时间:2011-09-04 07:31:12

标签: c# windows file transactions

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

如果没有,那么其他人如何解决这个问题呢? Windows上的数据库如何解决此问题?

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

2 个答案:

答案 0 :(得分:4)

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

如果您需要在旧版本的Windows或非NTFS分区上运行,则需要自己执行事务。这显然是非常重要的:在处理多个进程(包括通过共享进行远程访问)的同时获得完整的ACID功能,即使假设只使用您的访问方法(使用普通Win32 API的其他进程)打破事情)。

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

答案 1 :(得分:3)

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

在您的情况下,它可能是您要写入数据的文件的副本,而如果所有内容都已成功,则将原始文件替换为副本。

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

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

我们在VS IDE上使用的这些技术就像工业控制系统一样,取得了相当不错的成功。