Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2003.05.08;
Скачать: [xml.tar.bz2];

Вниз

Не могу побороть Disconnect   Найти похожие ветки 

 
Sergeeeee   (2003-04-16 19:02) [0]

Мое приложение работает с InterBase.
Использую стандартные компоненты IBDataBase, IBTransaction и т. д. Когда резко отрубаешь приложение от базы(напримет выключешь сервер), то приложение оень прочно виснет, вернее оно не виснет, а просто не дает ничего сделать - низакрыться ни подконектиться снова, а просто пишет сообщение, что сервер принудительно разорвал соединение, и это сообщение выскакивает раз за разом.
Можно ли как-то побороть это зло, ну хотя бы чтоб приложение просто закрывалось?


 
geg   (2003-04-17 16:20) [1]

Хорошый вопрос сам сейчас голову ломаю. Если что придумаю накатаю..


 
Соловьев   (2003-04-17 16:23) [2]

Использовать FIBPlus или почитать www.ibase.ru там есть статейка насчет IBx...


 
samalex   (2003-04-17 17:12) [3]

Попробуй с событии "BeforeDisconnect" IBDatabase -

procedure TForm1.IBDatabase1BeforeDisconnect(Sender: TObject);
begin
if MessageDlg("Нет соединения с БД. Закрыть программу?",
mtConfirmation, [mbYes, mbNo], 0) = mrYes then
begin
Halt(1);
end;
end;

Единственно, это сработает во время очередого запроса к БД, то есть не синхронно с разрывом.


 
Jaxtor   (2003-04-17 18:35) [4]

Вообще-то это проблема также есть в Delphi 6 и IBExpert...


 
XanderMan   (2003-04-17 20:55) [5]

> samalex

Не поможет. Это событие никогда не произойдет, если физически оборвать коннект.

> Sergeeeee

Единственное, что придумал, это два try except на Commit и Rollback и если попали во второй Except, то

if E is EIBInterBaseError then begin
ShowErrorText("Произошел обрыв соединения с сервером"+#13#10+
"Приложение будет закрыто"+#13#10+
"Все несохраненные изменения будут потеряны");
ExitProcess(2);
end

очень коряво, но хотя бы приложение можно закрыть :-(


 
XanderMan   (2003-04-18 08:44) [6]

Удалено модератором
Примечание: Сождание пустых сообщений, вмесо UP может получиться DOWN


 
kravchuk   (2003-04-18 17:12) [7]

нашел где то в Сети, сам не проверял, но люди говорили что работаит

Решение проблем дисконнекта в IBX



базируется на переписке ThreeDHead и Vlad Filippov:

окончательный вариант для IBX 6.03 выглядит так:

//--------------------------------------------
//IBCustomDataSet.pas
//--------------------------------------------
procedure TIBCustomDataSet.DoBeforeTransactionEnd(Sender: TObject);
begin
if Active then
Active := False;
if FQSelect <> nil then
try // <<--- My changes
FQSelect.FreeHandle;
except // <<--- My changes
end; // <<--- My changes
if FQDelete <> nil then
try // <<--- My changes
FQDelete.FreeHandle;
except // <<--- My changes
end; // <<--- My changes
if FQInsert <> nil then
try // <<--- My changes
FQInsert.FreeHandle;
except // <<--- My changes
end; // <<--- My changes
if FQModify <> nil then
try // <<--- My changes
FQModify.FreeHandle;
except // <<--- My changes
end; // <<--- My changes
if FQRefresh <> nil then
try // <<--- My changes
FQRefresh.FreeHandle;
except // <<--- My changes
end; // <<--- My changes
FInternalPrepared := false;
if Assigned(FBeforeTransactionEnd) then
FBeforeTransactionEnd(Sender);
end;
procedure TIBCustomDataSet.InternalClose;
begin
if Assigned(Transaction) then
Transaction.CheckAutoStop;
try // <<--- My changes
FQSelect.Close;
except // <<--- My changes
end; // <<--- My changes
ClearBlobCache;
FreeRecordBuffer(FModelBuffer);
FreeRecordBuffer(FOldBuffer);
FCurrentRecord := -1;
FOpen := False;
FRecordCount := 0;
FDeletedRecords := 0;
FRecordSize := 0;
FBPos := 0;
FOBPos := 0;
FCacheSize := 0;
FOldCacheSize := 0;
FBEnd := 0;
FOBEnd := 0;
ReallocMem(FBufferCache, 0);
ReallocMem(FOldBufferCache, 0);
BindFields(False);
FUpdatesPending := false;
if DefaultFields then
DestroyFields;
end;

продолжение следует...


 
kravchuk   (2003-04-18 17:14) [8]


//--------------------------------------------
IBSQL.pas
//--------------------------------------------
procedure TIBSQL.FreeHandle;
var
isc_res: ISC_STATUS;
begin
try
{ The following two lines merely set the SQLDA count
variable FCount to 0, but do not deallocate
That way the allocations can be reused for
a new query sring in the same SQL instance }
FSQLRecord.Count := 0;
FSQLParams.Count := 0;
if (FHandle <> nil) and (not CheckStatusVector([isc_network_error]))
then // <<--- My changes (NB)
begin
isc_res :=
Call(isc_dsql_free_statement(StatusVector, @FHandle, DSQL_drop),
False);
if (StatusVector^ = 1) and (isc_res > 0) and (isc_res <>
isc_bad_stmt_handle) and
(isc_res <> isc_lost_db_connection) then
IBDataBaseError;
end;
finally
FPrepared := False;
FHandle := nil;
end;
end;
//--------------------------------------------
//IBDatabase.pas
//--------------------------------------------
procedure TIBDatabase.InternalClose(Force: Boolean);
var
i: Integer;
begin
CheckActive;
{ Tell all connected transactions that we"re disconnecting.
This is so transactions can commit/rollback, accordingly
}
for i := 0 to FTransactions.Count - 1 do
begin
try
if FTransactions[i] <> nil then
Transactions[i].BeforeDatabaseDisconnect(Self);
except
if not Force then
raise;
end;
end;
for i := 0 to FSQLObjects.Count - 1 do
begin
try
if FSQLObjects[i] <> nil then
try // <<--- My changes
SQLObjects[i].DoBeforeDatabaseDisconnect;
except // <<--- My changes
end; // <<--- My changes
except
if not Force then
raise;
end;
end;
if (not HandleIsShared) then // <<--- My changes (NB)
begin // <<--- My changes (NB)
if (not CheckStatusVector([isc_network_error])) and //<<--- My changes
(NB)
(Call(isc_detach_database(StatusVector,@FHandle),False) > 0) and
//<<--- My changes (NB)
(not Force) then // <<--- My changes (NB)
IBDataBaseError;
end // <<--- My changes (NB)
else
begin
FHandle := nil;
FHandleIsShared := False;
end;
if not (csDesigning in ComponentState) then
MonitorHook.DBDisconnect(Self);
for i := 0 to FSQLObjects.Count - 1 do
if FSQLObjects[i] <> nil then
SQLObjects[i].DoAfterDatabaseDisconnect;
end;
procedure TIBTransaction.EndTransaction(Action: TTransactionAction;
Force: Boolean);
var
status: ISC_STATUS;
i: Integer;
begin
CheckInTransaction;
case Action of
TARollback, TACommit:
begin
if (HandleIsShared) and
(Action <> FDefaultAction) and
(not Force) then
IBError(ibxeCantEndSharedTransaction, [nil]);
for i := 0 to FSQLObjects.Count - 1 do
if FSQLObjects[i] <> nil then
try // <<--- My changes
SQLObjects[i].DoBeforeTransactionEnd;
except // <<--- My changes
end; // <<--- My changes



...................далее без изменений


 
Sergeeeee   (2003-04-18 18:12) [9]

Всем спасибо за помощь, а особенно
samalex-у , правда я еще не пробовал, но сама идея именно такая, а имменно физический обрыв сети.



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2003.05.08;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.009 c
14-23317
Num Lock
2003-04-14 09:35
2003.05.08
---|Ветка была без названия|---


8-23235
Сергей
2003-01-30 14:00
2003.05.08
Propotional draw


11-23048
Proton
2002-07-30 19:30
2003.05.08
RoterPro


1-23208
Slym
2003-04-25 07:36
2003.05.08
Нужна TreeView с чекбоксами


14-23357
Ekateryna
2003-04-18 15:28
2003.05.08
HELP ME!!!





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский