Запись транзакций в С# и Windows?
У меня есть файл данных, и время от времени мне нужно записать изменения в файл. Изменение состоит из изменения информации в нескольких местах. Например, изменение некоторых данных ближе к концу файла, а также изменение некоторой информации рядом с началом. Я хочу, чтобы две отдельные записи были либо успешными, либо обе неудачными, иначе они останутся в неопределенном состоянии и будут эффективно повреждены. Есть ли встроенная поддержка этого сценария в .NET или вообще?
Если нет, то как другим решить эту проблему? Как база данных Windows решает эту проблему?
UPDATE. Я не хочу использовать возможности Transactional NTFS, потому что он недоступен в старой версии Windows, такой как XP, и медленнее в сценарии перезаписывания файлов, как описано выше.
Ответы
Ответ 1
Если вы используете Windows 6 или более позднюю версию (Vista/7/2008/2008R2), файловая система NTFS поддерживает транзакции (в том числе в рамках распределенной транзакции): но вам нужно будет использовать P/Invoke для вызова Win32 API (см. этот question).
Если вам нужно запустить более старые версии Windows или разделы, отличные от NTFS, вам нужно будет выполнить транзакции самостоятельно. Это явно нетривиально: получение полной функциональности ACID при обработке нескольких процессов (включая удаленный доступ через общие ресурсы) при сбоях процессов и систем даже при условии, что будут использоваться только ваши методы доступа (какой-то другой процесс с использованием обычных API Win32, конечно, будет сломать вещи).
В этом случае база данных почти наверняка будет проще: есть несколько встроенных баз данных (SQL Compact Edition, SQL Lite,...), поэтому для базы данных не требуется серверный процесс.
Ответ 2
DB в основном использует концепцию журнала (по крайней мере, те, о которых я знаю). Идея заключается в том, что операция записи записывается в журнал до тех пор, пока Writer
не совершит транзакцию. (Конечно, это просто базовое описание, это так просто)
В вашем случае это может быть копия вашего файла, где вы собираетесь писать данные, и если все закончится с успехом, замените исходный файл на него копией.
Подстановка: переименуйте исходный файл, например, old
, переименуйте файл резервной копии, такой как original
.
Если сбой подстановки: это критическая ошибка, которую приложение должно обрабатывать с помощью стратегий отказоустойчивости. Может быть, он сообщил пользователю о неудачной операции сохранения и пытается восстановить. Кстати, в любой момент у вас есть обе копии вашего файла. Это когда операция записи только началась, а другая - при завершении операции записи.
Эти методы мы использовали в прошлых проектах на VS IDE, таких как системы промышленного контроля, с довольно хорошим успехом.