Как обеспечить координацию между файловой системой и базой данных? - PullRequest
8 голосов
/ 26 марта 2010

Я работаю над онлайн-проектом по управлению файлами. Мы храним ссылки на базу данных (сервер SQL) и файлы данных в файловой системе.

Мы сталкиваемся с проблемой координации между файловой системой и базой данных во время загрузки файла, а также в случае удаления файла. Сначала мы создаем ссылку в базе данных или храним файлы в файловой системе.

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

Пожалуйста, дайте мне какое-нибудь решение, как справиться с такой ситуацией. Мне это очень нужно.

Этот случай также происходит при удалении файла?

Ответы [ 4 ]

6 голосов
/ 26 марта 2010

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

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

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

Я бы также предложил сохранить хэш (например, MD5) файла в базе данных. Потратьте немного времени на его вычисление, но мне было очень полезно обнаруживать проблемы, например, если файл переименован в файловой системе по ошибке, но не в базе данных. Это также позволяет периодически выполнять проверку целостности, чтобы убедиться, что ничего не было прикручено.

Если такого подхода недостаточно (например, вы хотите, чтобы он был более устойчивым), я не вижу другого способа, кроме как сохранить двоичный файл в базе данных в LOB. Тогда это будет действительно транзакционно и безопасно.

1 голос
/ 13 июня 2011

Старый вопрос, который я знаю, но в пользу других читателей:

В зависимости от ваших операционных систем вы можете использовать Transactional TxF

http://msdn.microsoft.com/en-us/magazine/cc163388.aspx

0 голосов
/ 18 апреля 2014

FILESTREAM был представлен в SQL Server 2008 для решения именно этой проблемы.

Однако он поставляется с собственным набором проблем с реализацией .

0 голосов
/ 26 марта 2010

Рассматривайте два события (управление ссылкой и управление файлом) как одну транзакцию. Если один из них потерпит неудачу, верните другой. Тогда вам будет трудно попасть в ситуацию, когда они не синхронизированы. Откатывать операции с базами данных проще, чем операции с файловой системой.

...