Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.05.08;
Скачать: CL | DM;

Вниз

Не могу побороть 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;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.025 c
14-23306
C3H5(OH)3
2003-04-18 11:49
2003.05.08
Диалоги в ресурсах


9-22899
Эндрю2
2002-06-27 06:05
2003.05.08
Как сделать книгу рекордов в игре пятнашки


1-23233
Серг
2003-04-25 14:14
2003.05.08
Bitmap в Excel


9-22904
UNIVERSAL
2002-12-04 09:11
2003.05.08
3DS MAX 5.0


14-23285
Дмитрий К.К.
2003-04-22 05:59
2003.05.08
Именинники 22 апреля