Восстановление сессии в фоне
-
- Сообщения: 13
- Зарегистрирован: Ср 29 июл 2020 15:20
Восстановление сессии в фоне
Добрый день!
Возникла такая неприятная ситуация при использовании компонент ODAC (версия 10.3.9) в студии Embarcadero 10.1 Berlin.
Имеется форма, на ней кнопка, при нажатии на которую происходит загрузка данных структурированного файла в БД Oracle (версия 18с). Если грузим последовательно несколько файлов (или один файл несколько раз), то после каждой нечетной загрузки кроме первой (3-я, 5-я, 7-я и т.д.) происходит переподключение сессии (срабатывает событие OnAfterConnect на компоненте TOraSession). Опытным путем установил, что реконнект идет при обращении к методу Prepare компонента TOraStoredProc. Так как исходников не имею, то не могу понять причину происходящего. При подключении используется Direct. DisconnectedMode отключен.
Возникла такая неприятная ситуация при использовании компонент ODAC (версия 10.3.9) в студии Embarcadero 10.1 Berlin.
Имеется форма, на ней кнопка, при нажатии на которую происходит загрузка данных структурированного файла в БД Oracle (версия 18с). Если грузим последовательно несколько файлов (или один файл несколько раз), то после каждой нечетной загрузки кроме первой (3-я, 5-я, 7-я и т.д.) происходит переподключение сессии (срабатывает событие OnAfterConnect на компоненте TOraSession). Опытным путем установил, что реконнект идет при обращении к методу Prepare компонента TOraStoredProc. Так как исходников не имею, то не могу понять причину происходящего. При подключении используется Direct. DisconnectedMode отключен.
Re: Восстановление сессии в фоне
Пожалуйста уточните, используете ли Вы DisconnectedMode ? Приведите DDL-скрипт на создание используемой хранимой процедуры и пример кода работы с ней в Вашем проекте
-
- Сообщения: 13
- Зарегистрирован: Ср 29 июл 2020 15:20
Re: Восстановление сессии в фоне
При DisconnectedMode вылетало бы постоянно. Нет, я его не использую.
-
- Сообщения: 13
- Зарегистрирован: Ср 29 июл 2020 15:20
Re: Восстановление сессии в фоне
пример кода в Delphi:
Код: Выделить всё
TPkMop = class(TCustomOraPackage)
private
FSession: TOraSession;
procedure GetStoreProc;
protected
StoredProc: TOraStoredProc;
published
property Name;
property Session: TOraSession read GetSession write SetSession;
// property Cursor;
public
procedure ImpMVDDict_1207(const PStan: TList<Variant>;
const PId, PName, PAddr, PPrim: TList<string>);
end;
implementation
procedure TPkMop.GetStoreProc;
begin
if Assigned(StoredProc) then
FreeAndNil(StoredProc);
StoredProc := TOraStoredProc.Create(nil);
StoredProc.AutoCommit := False;
StoredProc.Session := Session;
end;
procedure TPkMop.ImpMVDDict_1207(const PStan: TList<Variant>;
const PId, PName, PAddr, PPrim: TList<string>);
var
LInd, LBuf: Integer;
LStan: TList<Variant>;
LID,LPName, LAddr, LPrim: TList<string>;
I, LLast: Integer;
begin
try
GetStoreProc;
LID := TList<string>.Create;
LPName := TList<string>.Create;
LAddr := TList<string>.Create;
LStan := TList<Variant>.Create;
LPrim := TList<string>.Create;
StoredProc.StoredProcName := 'FGV0.MOP.IMPORT_MVD_DICT_1207';
StoredProc.Prepare;
LInd := 0;
LBuf := 32000;
while (LBuf * LInd <= PId.Count) do
begin
LLast := Iff((LBuf * (LInd + 1) > PId.Count), PId.Count,
LBuf * (LInd + 1));
for I := (LBuf * LInd) to (LLast - 1) do
begin
LId.Add(PId[I]);
LPName.Add(PName[I]);
LAddr.Add(PAddr[I]);
LStan.Add(PStan[I]);
LPrim.Add(PPrim[I]);
end;
SetParam('P_ID', LId);
SetParam('P_NAME', LPName);
SetParam('P_ADDR', LAddr);
SetParam('P_STAN', LStan);
SetParam('P_PRIM', LPrim);
StoredProc.Execute;
Inc(LInd);
LId.Clear;
LPName.Clear;
LAddr.Clear;
LStan.Clear;
LPrim.Clear;
end;
finally
FreeAndNil(LId);
FreeAndNil(LPName);
FreeAndNil(LAddr);
FreeAndNil(LStan);
FreeAndNil(LPrim);
end;
end;
-
- Сообщения: 13
- Зарегистрирован: Ср 29 июл 2020 15:20
Re: Восстановление сессии в фоне
Код: Выделить всё
PROCEDURE import_mvd_dict ( p_id string_table,
p_name string_table,
p_addr string_table,
p_stan number_table,
p_prim string_table )is
dt date := sysdate;
ex number;
st number;
cur MOP_MVD%ROWTYPE;
l_id varchar2(4000);
l_name varchar2(4000);
l_addr varchar2(4000);
l_stan number;
l_prim varchar2(4000);
begin
-- основной цикл обработки входящих данных
for i in p_id.first..p_id.last loop
l_stan := p_stan(i);
if l_stan not in (0,1) then
fgv_err.raiserr( TA_ERRC, TA_PFX, 757, DEST_TA );
end if;
l_id := substr(trim(p_id(i)),1,4);
if l_id is null then
fgv_err.raiserr( TA_ERRC, TA_PFX, 759, DEST_TA );
end if;
l_name := substr(p_name(i),1,300);
l_addr := substr(p_addr(i),1,100);
l_prim := substr(p_prim(i),1,100);
select count(1) into ex from mop_mvd m where m.id = l_id;
if ex = 0
then -- добавление новой записи
st := l_stan * 2;
insert into mop_mvd (id,full_name,addr,stan,prim,date_add,date_edit,date_del)
values (l_id,l_name,l_addr,st,l_prim,dt,dt,case when st = 0 then dt else null end);
else -- редактирование существующей записи
select * into cur from mop_mvd m where m.id = l_id;
if cur.date_edit = dt then
fgv_err.raiserr( TA_ERRC, TA_PFX, 758, DEST_TA, l_id );
end if;
if nvl(cur.full_name,chr(0)) = nvl(l_name,chr(0))
and nvl(cur.addr,chr(0)) = nvl(l_addr,chr(0))
then -- ключевые реквизиты не изменились
st := l_stan * 1;
update mop_mvd m set m.prim = l_prim,
m.stan = st,
m.date_edit = dt,
m.date_del = case when st = 0 then nvl(m.date_del,dt) else null end
where m.id = l_id;
else -- обновление записи
st := l_stan * 3;
update mop_mvd m set m.full_name = l_name,
m.addr = l_addr,
m.prim = l_prim,
m.stan = st,
m.date_edit = dt,
m.date_del = case when st = 0 then nvl(m.date_del,dt) else null end
where m.id = l_id;
end if;
end if;
end loop;
-- "удаление" не упомянутых в файле записей
update mop_mvd m set m.stan = 0, m.date_del = nvl(m.date_del,dt) where m.date_edit < dt;
end import_mvd_dict;
Re: Восстановление сессии в фоне
Спасибо за предоставленную Вами информацию. Мы проверим работу наших компонентов согласно Вашего описания и сообщим Вам о результатах в самое ближайшее время
-
- Сообщения: 13
- Зарегистрирован: Ср 29 июл 2020 15:20
Re: Восстановление сессии в фоне
Добрый день! Есть какие-либо подвижки по моему вопросу?
Re: Восстановление сессии в фоне
Мы внимательно изучили присланную Вами информацию, но ее оказалось недостаточно для воспроизведения проблемы в нашем окружении. Пожалуйста с помощью формы e-support (https://www.devart.com/company/contactform.html) пришлите полный исходный код тестового примера, а также DDL-скрипт для создания объектов БД (таблиц, типов и т.д.),
которые необходимы для использования хранимой процедуры import_mvd_dict
которые необходимы для использования хранимой процедуры import_mvd_dict
-
- Сообщения: 13
- Зарегистрирован: Ср 29 июл 2020 15:20
Re: Восстановление сессии в фоне
Извините за долгий ответ. Поменялся приоритет задач на время.
Посредством формы e-support выслал тестовый пример с описанием необходимых действий.
Посредством формы e-support выслал тестовый пример с описанием необходимых действий.
Re: Восстановление сессии в фоне
Пожалуйста попробуйте отослать Ваш пример еще раз, т.к. к настоящему времени мы не получили на e-support Ваш запрос
-
- Сообщения: 13
- Зарегистрирован: Ср 29 июл 2020 15:20
Re: Восстановление сессии в фоне
Странно отправлял даже дважды. Сейчас отправлю еще раз
-
- Сообщения: 13
- Зарегистрирован: Ср 29 июл 2020 15:20
Re: Восстановление сессии в фоне
По техническим причинам Вы не могли некоторое время воспользоваться нашим сервисом e-support. Сейчас проблема решена, мы получили отправленный Вами пример и приступили к его анализу.
-
- Сообщения: 13
- Зарегистрирован: Ср 29 июл 2020 15:20
Re: Восстановление сессии в фоне
Отправил еще раз архив с тестовым примером
Re: Восстановление сессии в фоне
Спасибо за составленный Вами пример. Мы внимательно изучили его работу и убедились, что Вы используете режим DisconnectedMode. Пожалуйста отключите этот режим :
и сообщите нам, воспроизводится ли проблема без использования DisconnectedMode
Код: Выделить всё
function TfrmConnectDlg.DoConnect: TModalResult;
begin
...
MainSession.Options.DisconnectedMode := False;
...
end;
и сообщите нам, воспроизводится ли проблема без использования DisconnectedMode