Запись транзакционных файлов в C # и Windows? - PullRequest
10 голосов
/ 04 сентября 2011

У меня есть файл данных, и время от времени мне нужно записывать изменения в файл. Изменение состоит из изменения информации в более чем одном месте. Например, изменив некоторые данные в конце файла, а также изменив некоторые данные в начале. Я хочу, чтобы две отдельные записи либо обе успешно, либо обе потерпели неудачу, в противном случае они остаются в неопределенном состоянии и эффективно повреждены. Есть ли встроенная поддержка для этого сценария в .NET или вообще?

Если нет то как другим решить эту проблему? Как база данных в Windows решает эту проблему?

ОБНОВЛЕНИЕ : я не хочу использовать возможность транзакционной NTFS, поскольку она недоступна в более старых версиях Windows, таких как XP, и медленно в сценарии перезаписи файлов, как описано выше.

Ответы [ 2 ]

4 голосов
/ 04 сентября 2011

Если вы используете Windows 6 или более позднюю версию (Vista / 7/2008 / 2008R2), файловая система NTFS поддерживает транзакции (в том числе внутри распределенной транзакции): но вам потребуется использовать P / Invoke для вызова Win32 API (см. Это вопрос ).

Если вам нужно работать на более старых версиях Windows или на разделах, отличных от NTFS, вам придется выполнять транзакции самостоятельно. Это определенно нетривиально: получение полной функциональности ACID при одновременной обработке нескольких процессов (включая удаленный доступ через общие ресурсы) в рамках процессов и сбоев системы, даже если предположить, что будут использоваться только ваши методы доступа (конечно, некоторые другие процессы, использующие обычные API-интерфейсы Win32) сломать вещи).

В этом случае база данных почти наверняка будет проще: существует ряд внутрипроцессных баз данных (SQL Compact Edition, SQL Lite, ...), поэтому база данных не требует серверного процесса.

3 голосов
/ 04 сентября 2011

БД в основном использует концепцию журнала (по крайней мере, ту, о которой я знаю). Идея состоит в том, что операция записи записывается в журнал до тех пор, пока Writer не совершит транзакцию. (Конечно, это просто базовое описание, это так просто)

В вашем случае это может быть копия вашего файла, в которую вы собираетесь записать данные, и , если все закончилось успешно , заменить исходный файл его копией.

Подстановка: переименовать исходный файл как old, переименовать файл резервной копии как original.

Если замена не удалась: это критическая ошибка, которую приложение должно обрабатывать с помощью стратегий отказоустойчивости. Возможно, он проинформировал пользователя о неудачной операции сохранения и попытался восстановить. Кстати, в любой момент у вас есть обе копии вашего файла. Тот, когда операция записи только началась, и тот, когда операция записи завершилась.

Это методы, которые мы использовали в предыдущих проектах на VS IDE, подобных системам для промышленного управления, с довольно хорошим успехом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...