Атомная модификация файлов в нескольких сетях - PullRequest
0 голосов
/ 11 мая 2009

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

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

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

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

Мое первоначальное предположение было:

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

if (isAtomic)
{
    //Do things
}

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

Ответы [ 3 ]

2 голосов
/ 11 мая 2009

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

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

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

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

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

1 голос
/ 11 мая 2009

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

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

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

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

0 голосов
/ 04 сентября 2013

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

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

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

...