IBX Обрыв соединения
[COLOR=indigo][SIZE=3]А что? [/SIZE] [/COLOR]
Да ниче не происходит - так и "висят" пока не уничтожиться форма которой они принадлежат
[COLOR=indigo][SIZE=3]А что? [/SIZE] [/COLOR]
Хотелось бы переконнектиться к другой базе и продолжить работу. Как-нибуть можно их в нормальное состояние привести? Проблема еще в том что компонентов много.
Хотелось бы переконнектиться к другой базе и продолжить работу. Как-нибуть можно их в нормальное состояние привести? Проблема еще в том что компонентов много.
Так та из одной программы устанавливаещь несколько соеденений с БД (не путай БД и таблицы)
Так та из одной программы устанавливаещь несколько соеденений с БД (не путай БД и таблицы)
Это можно организовать с помощью одного IBDataBase? Или нужно несколько IBDatabase-ов каждый к своей базе подцепленный? С одной и той же базой несколько соединений держать смысла нет, под обрывом понимается, что кто-то выдернул сетевой шнур из сервера.
Это можно организовать с помощью одного IBDataBase? Или нужно несколько IBDatabase-ов каждый к своей базе подцепленный? С одной и той же базой несколько соединений держать смысла нет, под обрывом понимается, что кто-то выдернул сетевой шнур из сервера.
У тебя сколько физически БД если одна то используй один IBDatabase
У тебя сколько физически БД если одна то используй один IBDatabase
Баз много все они лежат на разных машинах, при падении главной проги должны переходить на одну из резервных.
При падении чтобы все закрыть вызываю у IBDatabase метод ForceClose(); Подсоединяюсь к резервной тем же IBdatabase-ом, но при работе IBSQL-я при вызове ExecQuery вылетает exception "Invalid statement handle". Что может быть не так?
Далее меняешь информацию по соеденению и коннектишся опять
IBDatabase->Connected = false - закрывает все
Далее меняешь информацию по соеденению и коннектишся опять
Да, но после этого всем компонентам датамодуля надо дать новый handle на базу.
Кто-нибуть знает как пробежать по всем компонентам определенного типа, например IBSQL?
for(int i = 0; i < Form4->ComponentCount-1; i++)
if(Form4->Components->ClassNameIs("TIBSQL"))
{
(TIBSQL *)Form4->Components->Database = IBDatabase1;
(TIBSQL *)Form4->Components->Transaction = IBTRansaction1;
}
Но это только для одной формы
Так что тебе необходимо создать в каждой форме функцию что то типа
void __fastcall INI_IB(TIBDatabase *a, TIBTransaction *b)
{
for(int i = 0; i < Form4->ComponentCount-1; i++)
if(Form4->Components->ClassNameIs("TIBSQL"))
{
(TIBSQL *)Form4->Components->Database = a;
(TIBSQL *)Form4->Components->Transaction = b;
}
}
eventsTA.RemoveDatabases;
eventsTA.AddDatabase(DB1);
events.Close;
events.Database := DB1;
events.Transaction := eventsTA;
events.Close;
events.SelectSQL.Clear;
events.SelectSQL.Add('select * from events');
events.open; //Вот ту ошибка вылетает.
DB1 - IBDataBase;
eventsTA - IBTransaction;
events - IBDataset;
Такое ощущение, что events пытается обратиться по-старому DBHanlde, хотя events.Database := DB1; должна прописать новый.
У компонента IBSQL есть метод FreeHanlde, у TIBDataset-a есть что-нить подобное?
Я сделал DLL, в ней функция в которую передается IBdatabase так вот при проектировании все работает нормально - а когда программа выполняется если IBSQL опять не поменять указатель вылетает ошибка как у тебя. Я решил эту проблему так
R_MAIN->IBDatabase1 = (TIBDatabase *) BASE;
R_MAIN->IBTransaction1->DefaultDatabase = R_MAIN->IBDatabase1;
R_MAIN->IBSQL1->Database = R_MAIN->IBDatabase1;
R_MAIN->IBDataSet1->Database = R_MAIN->IBDatabase1;
И только потом стартую транзакции и все остальное
Судя по всему когда ты открываешь соеденение - выделяется область памяти и при повторном открытии все компоненты ссылаются на другую область памяти
Я сделал DLL, в ней функция в которую передается IBdatabase так вот при проектировании все работает нормально - а когда программа выполняется если IBSQL опять не поменять указатель вылетает ошибка как у тебя. Я решил эту проблему так
R_MAIN->IBDatabase1 = (TIBDatabase *) BASE;
R_MAIN->IBTransaction1->DefaultDatabase = R_MAIN->IBDatabase1;
R_MAIN->IBSQL1->Database = R_MAIN->IBDatabase1;
R_MAIN->IBDataSet1->Database = R_MAIN->IBDatabase1;
И только потом стартую транзакции и все остальное
Спасибо, что помогаешь.
Проблему с IBSQL-ем('Invalid statement handle') я решил. Сейчас проблема с 'Access violation'.
По идеи при обрыве соединения должна работать следующая схема:
1. принудительно закрываем соединение. Например с помощью ForceClose()
2. Коммитим все открытые транзакции, хотя их не должно быть, наверно.
3. Закрываем все Dataset-ы.
4. Прописываем путь к резервной БД и пытаемся подсоединиться тем же компонентом(IBDatabase)
5. Всем компонентам в свойство Database прописываем component->Database = IBDatabase;
Для IBSQL эта схема работает отлично, они продолжают работать как будто обрыва и не было, а IBDataset при вызове open() падает с ошибкой 'Access violation'. В отладчике смотрел, свойство DBHandle у него обновляется. Может быть это происходит из-за того что у Dataset-а в Design-time созданы поля?