Функция 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", оказывается, также игнорируется, если обернут в игнор ошибок.


Log in to reply