Функция LOCK через базу данных

Поддержка
  • Всем привет!

    Хочу реализовать функцию Lock для многопоточного бота (пока один поток работает со строкой, второй берет следующую). Все было бы просто, если бы использовались ресурсы с параметром одновременных использований = 1. Но у меня используется база данных BAS-а без загрузки в систему ресурсов (потому что много операций с БД, которые гораздо проще делать напрямую с БД, а не через список в ресурсах).

    1. Я создал отдельную колонку lock в БД
    2. Я присваиваю lock=process, когда один из потоков начал работать с этой строкой в БД.
    3. Скрипт работает со строкой 2-5 минут.
    4. Я присваиваю lock=done, когда поток закончил работу со строкой.
    5. Другие потоки не берут строки с lock=process.

    Проблема в том, что скрипт за эти 2-5 минут работы может сфейлиться во множестве мест (примерно с вероятностью 20%, таков сайт). И у строки остается lock=process (по сути зависает), и строка больше не участвует в работе.

    Вопрос: как при фейле потока снимать lock=process со строки? Ну или может не при фейле, но максимально быстро после него. Не могу придумать, буду рад любым подсказкам.

  • @doupiu вроде очевидно весь код в игнор ошибок, при любом исходе сначала разлочить строку, а потом уже выкинуть ошибку если надо

  • @UserTrue звучит неплохо, должно работать, правда придется с десяток if WAS_ERROR навернуть) Спасибо, буду делать

  • @doupiu said in Функция LOCK через базу данных:

    @UserTrue звучит неплохо, должно работать, правда придется с десяток if WAS_ERROR навернуть) Спасибо, буду делать

    Зачем? Просто все действия из функции Main переместите в созданную функцию, а её вызов оберните в игнор ошибок

  • @Fox а если у меня там уже есть внутри блоки с игнором ошибок? Что произойдет, если поток поймает ошибку в таком действии? Он выйдет из одного игнора ошибок или из всех сразу? Грубо говоря: в игноре ошибок работает вложенность?

  • @Fox а также: если в скрипте настроены куча выходов из него вида if что-то - fail, то я так понимаю игнор ошибок тут не поможет и перед каждым fail нужно снимать lock отдельно. Это я к тому, что решение "обернуть все в один игнор" не 100% рабочее тут)

  • Все как Фокс сказал, оберните в игнор, и снимайте Лок при ошибках, ну и на каждом жёстком выходе тоже надо перед выходом снимать.

    И еще - в лок достаточно писать 1 или 0

  • @doupiu said in Функция LOCK через базу данных:

    @Fox а если у меня там уже есть внутри блоки с игнором ошибок? Что произойдет, если поток поймает ошибку в таком действии? Он выйдет из одного игнора ошибок или из всех сразу? Грубо говоря: в игноре ошибок работает вложенность?

    При ошибки вложенного игнора ошибок сработает самый вложенный, так как в нём произойдёт ошибка, а во внешних ошибки не будет, так как она уже в блоке игнора. Вам проще и быстрее было попробовать самому проверить в BAS

    @doupiu said in Функция LOCK через базу данных:

    @Fox а также: если в скрипте настроены куча выходов из него вида if что-то - fail, то я так понимаю игнор ошибок тут не поможет и перед каждым fail нужно снимать lock отдельно. Это я к тому, что решение "обернуть все в один игнор" не 100% рабочее тут)

    Во первых, в вашем первом сообщении нет упоминаний ни про if, ни про fail, я предложил решение под данные, что вы предоставили. Но даже в этом случае можно выйти из положения, например в текст действия fail поместить кодовое слово (например %fail%), а после игнора ошибок в Main поставить условие, если в тексте ошибки присутствует слово %fail%, то завершить поток с ошибкой не снимая блокировки элемента базы данных

  • @Fox вложенность игнор в игноре работает, да, проверил. Снятие lock настроил после общего блока игнора ошибок + перед каждым fail внутри скрипта. За ночь 300 записей из БД перешли в статус done без зависания в статусе process на ошибках, так что все ок.

    Спасибо за советы. Я упомянул в топике узкие места решения "обернуть все в один игнор" не для "поругаться", а лишь для того, чтобы потом люди при поиске смогли найти решение для себя)

  • @doupiu поправка: сброс lock перед каждым Fail не нужен. Кубик "Fail", оказывается, также игнорируется, если обернут в игнор ошибок.

  • 0 Votes
    36 Posts
    3319 Views
  • 0 Votes
    5 Posts
    717 Views
  • 0 Votes
    4 Posts
    691 Views
  • 0 Votes
    7 Posts
    2068 Views
  • 0 Votes
    19 Posts
    8382 Views