简体   繁体   English

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

[英]Transactional file writing in C# and Windows?

I have a data file and from time to time I need to write a change to the file. 我有一个数据文件,有时我需要写一个文件的更改。 The change consists of changing information in more than one place. 变更包括在多个地方更改信息。 For example, changing some data near the end of the file and also changing some information near the start. 例如,更改文件末尾附近的某些数据,并更改启动附近的某些信息。 I want the two separate writes to either both succeed or both fail, otherwise it is left in uncertain state and effectively corrupted. 我希望两个单独的写入要么成功要么都失败,否则它将处于不确定状态并且实际上已损坏。 Is there any builtin support for this scenario in .NET or in general? 在.NET或一般情况下,是否有针对此场景的内置支持?

If not then how to others solve this issue? 如果不是那么如何解决这个问题? How does a database on Windows solve this issue? Windows上的数据库如何解决此问题?

UPDATE : I do not want to use the Transactional NTFS capability because it is not available on older version of Windows such as XP and it is slow in the file overwrite scenario as described above. 更新 :我不想使用事务性NTFS功能,因为它在旧版本的Windows(如XP)上不可用,并且在文件覆盖方案中速度很慢,如上所述。

If you are using Windows 6 or later (Vista/7/2008/2008R2) the NTFS filesystem supports transactions (including within a distributed transaction): but you will need to use P/Invoke to call Win32 APIs (see this question ). 如果您使用的是Windows 6或更高版本(Vista / 7/2008 / 2008R2),则NTFS文件系统支持事务(包括在分布式事务中):但您需要使用P / Invoke来调用Win32 API(请参阅此问题 )。

If you need to run on older versions of Windows, or non-NTFS partitions you would need to perform the transactions yourself. 如果需要在旧版本的Windows或非NTFS分区上运行,则需要自己执行事务。 This is decidedly non-trivial: getting full ACID functionality while handling multiple processes (including remote access via shares) across process and system crashes even with the assumption that only your access methods will be used (some other process using normal Win32 APIs would of course break things). 这绝对是不平凡的:在处理多个进程(包括通过共享进行远程访问)的过程中获得完整的ACID功能,即使假设只使用您的访问方法(使用普通Win32 API的其他进程)打破事情)。

In this case a database will almost certainly be easier: there are a number of in-process databases (SQL Compact Edition, SQL Lite, ...) so a database doesn't require a server process. 在这种情况下,数据库几乎肯定会更容易:有许多进程内数据库(SQL Compact Edition,SQL Lite,...),因此数据库不需要服务器进程。

DB basically uses a Journal concept (at least those one I'm aware of). DB基本上使用了Journal概念(至少是我所知道的那个)。 An idea is, that a write operation is written in journal until Writer doesn't commit a transaction. 一个想法是,写入操作是在日志中写入的,直到Writer不提交事务。 (Sure it's just basic description, it's so easy) (当然这只是基本的描述,它很容易)

In your case, it could be a copy of your file, where you're going to write a data, and if everything finished with success , substitute original file with it's copy. 在您的情况下,它可能是您的文件的副本,您将在其中写入数据, 如果一切都成功完成请将原始文件替换为副本。

Substitution is: rename original file like a old , rename backup file like a original . 替换是:将原始文件重命名为old ,重命名备份文件,如original文件。

If substitution fails: this is a critical error, that application should handle via fault tolerance strategies. 如果替换失败:这是一个严重的错误,应用程序应该通过容错策略来处理。 Could be that it informed a user about a failed save operation, and tries to recover. 可能是它告知用户有关失败的保存操作,并尝试恢复。 By the way in any moment you have both copies of your file. 顺便提一下,你有两份文件副本。 That one when write operation just started, and that one when write operation finished. 当写操作刚刚开始时,那一个,当写操作完成时。

This techniques we used on past projects on VS IDE like systems for industrial control with pretty good success. 我们在VS IDE的过去项目中使用的这种技术就像工业控制系统一样,取得了相当不错的成功。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM