Форум: "Базы";
Текущий архив: 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.007 c