Глюк в FB? Потокобезопасность FB API?
Глюк в FB? Потокобезопасность FB API?
Firebird-2.0.3.12981-1 Windows XP sp2
1. Открываем базу из основного потока приложения
dbName:= 'localhost:MY_BASE'; // TCP/IP MY_BASE в alliases.conf
isc_attach_database(@status, 0, PChar(dbName), @DB_Handle, dpb_length, @dpb_buffer);
2. Стартуем транзакцию из второго потока.
tpb_buffer[0]:= Char(isc_tpb_version3);
tpb_buffer[1]:= Char(isc_tpb_write);
tpb_buffer[2]:= Char(isc_tpb_read_committed);
tpb_buffer[3]:= Char(isc_tpb_no_rec_version);
tpb_buffer[4]:= Char(isc_tpb_wait);
isc_start_transaction(@status, @IBTrans_Handle, 1, @DB_Handle, 5, @tpb_buffer)
3. Из того же потока делаем вызовы
isc_create_blob2(@status, @DB_Handle, @IBTrans_Handle, @blob_handle_wav, @blob_id_wav, 0, nil);
и начинаем вызывать по мере необходимости.
isc_put_segment(@status, @blob_handle_wav, WriteCacheBufferPos, @WriteCacheBuffer);
Переменные IBTrans и blob_handle_wav потоковые.
Создаем еще один поток со своими переменными IBTrans и blob_handle_wav
Пункт 2 и3 повторяем из этого потока и FB лежит.
Симптомы такие isc_start_transaction проходит на ура и возвращает какой-то Handle, похожий на правду.
Если посмотреть netstat, то видно что при этом возникает новое TCP/IP подключение к порту 3050.
После чего isc_create_blob2 возвращает код, что транзакция не стартовала, хотя ему передается полученный Handle. А FB при этом разлетается.
Методом научного тыка было установлено, что проблема устраняется если для каждого потока делать своё подключение к БД при помощи isc_attach_database. В этом случае все работает правильно, однако при помощи описанной последовательности по-моему можно положить любой сервер.
Вот такая панимаиш загогулина (с).
1. Открываем базу из основного потока приложения
dbName:= 'localhost:MY_BASE'; // TCP/IP MY_BASE в alliases.conf
isc_attach_database(@status, 0, PChar(dbName), @DB_Handle, dpb_length, @dpb_buffer);
2. Стартуем транзакцию из второго потока.
tpb_buffer[0]:= Char(isc_tpb_version3);
tpb_buffer[1]:= Char(isc_tpb_write);
tpb_buffer[2]:= Char(isc_tpb_read_committed);
tpb_buffer[3]:= Char(isc_tpb_no_rec_version);
tpb_buffer[4]:= Char(isc_tpb_wait);
isc_start_transaction(@status, @IBTrans_Handle, 1, @DB_Handle, 5, @tpb_buffer)
3. Из того же потока делаем вызовы
isc_create_blob2(@status, @DB_Handle, @IBTrans_Handle, @blob_handle_wav, @blob_id_wav, 0, nil);
и начинаем вызывать по мере необходимости.
isc_put_segment(@status, @blob_handle_wav, WriteCacheBufferPos, @WriteCacheBuffer);
Переменные IBTrans и blob_handle_wav потоковые.
Создаем еще один поток со своими переменными IBTrans и blob_handle_wav
Пункт 2 и3 повторяем из этого потока и FB лежит.
Симптомы такие isc_start_transaction проходит на ура и возвращает какой-то Handle, похожий на правду.
Если посмотреть netstat, то видно что при этом возникает новое TCP/IP подключение к порту 3050.
После чего isc_create_blob2 возвращает код, что транзакция не стартовала, хотя ему передается полученный Handle. А FB при этом разлетается.
Методом научного тыка было установлено, что проблема устраняется если для каждого потока делать своё подключение к БД при помощи isc_attach_database. В этом случае все работает правильно, однако при помощи описанной последовательности по-моему можно положить любой сервер.
Вот такая панимаиш загогулина (с).
спасибо за гениальное открытие! Вы помогли всем, кто не читает FAQ!Методом научного тыка было установлено, что проблема устраняется если для каждого потока делать своё подключение к БД при помощи isc_attach_database.
www.ibase.ru/ibfaq.htm#threads
если серьезно, то этот пункт у меня в FAQ уже лет десять. Правда, не всякое измывательство над клиентом приводит к падению сервера. И не всякой версии.
Re: Глюк в FB? Потокобезопасность FB API?
Синхронизировать потоки нужно, вокруг вызовов АПИ.Vit писал(а):Создаем еще один поток со своими переменными IBTrans и blob_handle_wav
Пункт 2 и3 повторяем из этого потока и FB лежит.
Та ты шо !Vit писал(а):Симптомы такие isc_start_transaction проходит на ура и возвращает какой-то Handle, похожий на правду.
Если посмотреть netstat, то видно что при этом возникает новое TCP/IP подключение к порту 3050.
ФАК читать мы не приученыVit писал(а):Методом научного тыка было установлено, что ...
Нет упал как раз сервер, вот в чем основная мысль, как верно заметил kdv. По-моему это не есть гуд, когда любой жлоб при помощи специально написанного кривого клиента легко кладет сервер. Если бы сервер прибивал такого клиента то все было бы логично.hvlad писал(а):Я в этом сильно сомневаюсь. Скорее упал клиент, или даже не упал, а начал выдавать "неожиданные" ошибки.kdv писал(а):тем не менее, основная мысль в посте о том, что сервер падает при таких операциях.
В любом случае - эта хрень должна уйти в 2.5
В списке процессов отсутствовал fbserver.exe.WildSery писал(а):И как ты это увидел? Что в логе сервера написано?Vit писал(а):Нет упал как раз сервер
Приходилось стартовать сервис руками. (Автоматический перезапуск у меня отключен и гвардеец тоже).
В логе действительно были ошибки клиента (много), но чем мне это поможет, сервер же таки лежал?
Упрек не по адресу. FAQ я читал.kdv писал(а):спасибо за гениальное открытие! Вы помогли всем, кто не читает FAQ!
www.ibase.ru/ibfaq.htm#threads
если серьезно, то этот пункт у меня в FAQ уже лет десять. Правда, не всякое измывательство над клиентом приводит к падению сервера. И не всякой версии.
Я полагал что проблема в IBX, а не в самом FB API.
Например VCL непотокобезопасный, а вот Windows API ,безопасный (за совсем редкими и экзотическими исключениями).
Или 10000. Будут ли какието проблемы с таким количеством коннектов?kostyl писал(а):А можно спросить (я читал FAQ): тоесть будет все нормально если я создаю треад у которого есть свой IBDataBase IBTransaction IBSQL, и еще таких же 1000 и работаю из одного клиента ими параллельно на servername:c\........?
конечно будут. операционная система не резиновая же. Сколько сможет сокетов открыть, столько и даст. Например RedHat Linux без изменения конфигов и перекомпиляции ядра дает около 600 коннектов.
Под виндой, суперсервер - около 5000. Да ты и сам можешь проверить - в цикле создавай IBDatabase, и выводи +1.
Только вот вопрос - нафига это?
Под виндой, суперсервер - около 5000. Да ты и сам можешь проверить - в цикле создавай IBDatabase, и выводи +1.
Только вот вопрос - нафига это?
я имел в виду 10 тысяч потоков и соединений. куда это? Клиент-сервер такое кол-во соединений не осилит, из-за ограничений операционки или железа. Да и даже на гигабитной сети такое число соединений потребует сильно дорогого сетевого железа.
В трехзвенке, опять же, такое количество соединений с СУБД избыточно на пару порядков.
Вообще этот вопрос из разряда "как мне обеспечить вставку миллиона записей в секунду" или "как работать с 10 терабайтной БД" - люди, перед которыми стоит такая задача в реале, уже обладают достаточным опытом и не задают подобных вопросов. А кто задает - не обладает достаточными знаниями для решений даже близко стоящих задач, однозначно.
В трехзвенке, опять же, такое количество соединений с СУБД избыточно на пару порядков.
Вообще этот вопрос из разряда "как мне обеспечить вставку миллиона записей в секунду" или "как работать с 10 терабайтной БД" - люди, перед которыми стоит такая задача в реале, уже обладают достаточным опытом и не задают подобных вопросов. А кто задает - не обладает достаточными знаниями для решений даже близко стоящих задач, однозначно.
Спасибо за ответы. Я подумаю действительно ли мне это надо.
PS:Так, что теперь прикажете не рашать? Я не пойму зачем это всё писать? Люди то, люди это... Это же форум. Тут люди задают вопросы, а, обладающие достаточным опытом, отвечают. Если я спрашиваю - я не знаю, "однозначно".kdv писал(а):люди, перед которыми стоит такая задача в реале, уже обладают достаточным опытом и не задают подобных вопросов. А кто задает - не обладает достаточными знаниями для решений даже близко стоящих задач, однозначно.