Атомарная модификация файлов в нескольких сетях

StackOverflow https://stackoverflow.com/questions/848550

  •  21-08-2019
  •  | 
  •  

Вопрос

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

Каждый раз, когда запускается это приложение, будет добавлен / удален / изменен ровно один элемент (не больше и не меньше).

Первоначально приложение открывает каждый XML-файл, добавляет / удаляет / изменяет элемент на соответствующем узле и сохраняет файл или выдает ошибку, если это невозможно (не удается получить доступ к общему сетевому ресурсу, время ожидания и т.д.)

Как мне сделать это атомарным?

Мое первоначальное предположение состояло в том, чтобы:

foreach (var path in NetworkPaths)
    if (!File.Exists(path)
        isAtomic = false;

if (isAtomic)
{
    //Do things
}

Но я вижу, что это заходит так далеко.Есть ли другой способ сделать это или направление, на которое мне могут указать?

Это было полезно?

Решение

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

Я бы сделал что-то вроде проверки для каждого файла - если он не существует, выбросьте.

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

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

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

Другие советы

Я предлагаю следующее решение.

  • Попробуйте открыть все файлы с блокировкой записи.
    • Если один или несколько завершатся неудачей, выполните прерывание.
    • Измените и удалите все файлы.
      • Если один или несколько завершатся неудачей, откатите уже измененные файлы обратно и снова промойте их.
  • Закройте все файлы.

Если откат завершится неудачей ...что ж ...пробуйте снова, и пробуйте снова, и пробуйте снова...и сдаваться в непоследовательном состоянии.

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

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

  • подготовьте следующую версию файла
  • запишите его во временный файл с другим именем.
  • Получите самый высокий номер версии
  • увеличьте эту версию на единицу
  • переименуйте временный файл в новый файл
  • удалите старые файлы (вы можете сохранить, например2 из них)

как читатель вы это делаете - найдите файл с самой высокой версией - прочитайте его

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top