Вопрос про upload файлов

pr1

Новичок
Здравствуйте,

Допустим на сайте есть возможность загружать файлы. Файл загружается в папку, а путь к этому файлу хранится в базе данных. Интересует решение проблем с транзакциями. Т.е допустим файл загрузился, но сервер упал (или произошла какая-то другая ошибка) и путь к этому файлу в базе не сохранился. Единственное что приходит в голову, код который делает upload писать в модели внутри транзакций. Сперва записывать данные в базу, после этого делать upload. Как вы решаете такие проблемы?
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Не вижу проблемы, твой "упавший сервер" проблема надуманная.

1. Запрос на сервер
2. Перемещение файла
3. Если файл переместился успешно - запись данных в базу
4. Если инфа о файле в БД не записалась - файл снести (написать данные о файле в temp лог и дописать потом, или что там тебе угодно)
 
  • Like
Реакции: pr1

Фанат

oncle terrible
Команда форума
Я не понял этого вопроса.
Транзакция - это не магический способ обеспечить работу сервера без сбоев.
Это всего лишь способ убедиться в том, что все операции прошли успешно, или - в противном случае - не выполнилась ни одна.
А больше я никакого объяснения слову "транзакция" в этом вопросе придумать не могу.
Можно подробнее объяснить каким боком тут транзакции и какую, собственно, проблему требуется решить?
 

pr1

Новичок
Я не понял этого вопроса.
Транзакция - это не магический способ обеспечить работу сервера без сбоев.
Это всего лишь способ убедиться в том, что все операции прошли успешно, или - в противном случае - не выполнилась ни одна.
А больше я никакого объяснения слову "транзакция" в этом вопросе придумать не могу.
Можно подробнее объяснить каким боком тут транзакции и какую, собственно, проблему требуется решить?
Насчет транзакции как раз это и имел ввиду. Когда гарантированно выполняются 2 операции.
1. Файл успешно сохраняется
2. Данные о файле записываются в базу.

В случае сбоя сделать откат.
 

AnrDaemon

Продвинутый новичок
Откат по-вашему, это что-то совершенно отдельное, к транзакции не относящееся?
 

Фанат

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

То есть сначала надо определиться с вопросом, какую проблему создают загруженные, но не привязанные к БД файлы. Если чисто эстетические, то такие файлы можно чистить регулярным запуском скрипта-чистильщика. Всё остальное заведомо не гарантирует очистку. Например в варианте, предложенном codex, может побиться временный файл.

Если проблема серьезнее, чем просто "где-то болтается беспризоный файл", то надо её сформулировать, и тогда тебе помогут ее решить
 
  • Like
Реакции: pr1

pr1

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

то это никак не поможет от висячих файлов.

То есть сначала надо определиться с вопросом, какую проблему создают загруженные, но не привязанные к БД файлы. Если чисто эстетические, то такие файлы можно чистить регулярным запуском скрипта-чистильщика. Всё остальное заведомо не гарантирует очистку. Например в варианте, предложенном codex, может побиться временный файл.

Если проблема серьезнее, чем просто "где-то болтается беспризоный файл", то надо её сформулировать, и тогда тебе помогут ее решить
Я неправильно выразил мысли. Эта тема была создана не с целью решить реальную проблему, а скорее узнать у опытных коллег, варианты решения проблемы "висячих файлов". В принципе ответ на свой вопрос я получил. Спасибо.
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Вапсче я через нолик... c0dex =\

@Фанат , про какой временный файл ты писал? который генерится сервером в момент загрузки?
 

pr1

Новичок
это никак не поможет от висячих файлов.
Почему не поможет? Например такой псевдокод
Код:
try {
    
    DB::beginTransaction();

    if  (DB::insert()->rowCount() < 1) {
        return false;
    }
      
    if  (Upload::upload() === false) {
        return false;
    }
      
    DB::commit();

    return true;

} catch () {

   DB::rollBack();

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

Фанат

oncle terrible
Команда форума
во-первых, инсерт тут лишний. достаточно просто начать транзакцию, а в базу вставлять уже после загрузки.
во-вторых, изначально сценарий был другой:
Т.е допустим файл загрузился, но сервер упал
то есть сервер падает между 11 и 13 строчками.
при чем здесь "в базу ничего не запишется" если вопрос был не про лишнюю инфу в базе а про лишний файл?

@c0dex,
написать данные о файле в temp лог
 

fixxxer

К.О.
Партнер клуба
@pr1, транзакция может зафейлиться не при инсерте, а при коммите. Если ты в catch будешь зачищать загруженный файл, будет ближе. Но всегда остается вариант "после upload() сегфолтнулся php / дернули рубильник / упал метеорит". Эту проблему обычно никто не решает, ну валяется с вероятностью 0.01% бесхозный файлик, да и хрен с ним. Если хочется ее решить в теории, можно сначала (до всей этой твоей транзакции) записывать куда-нибудь путь к файлу (в лог, скажем), лог раз в N часов ротировать и проверять, на все ли файлы в сротированном есть ссылка в базе.
 
  • Like
Реакции: pr1
Сверху