Страница 1 из 2
Восстановление сессии в фоне
Добавлено: Ср 29 июл 2020 15:35
yuryleon77
Добрый день!
Возникла такая неприятная ситуация при использовании компонент ODAC (версия 10.3.9) в студии Embarcadero 10.1 Berlin.
Имеется форма, на ней кнопка, при нажатии на которую происходит загрузка данных структурированного файла в БД Oracle (версия 18с). Если грузим последовательно несколько файлов (или один файл несколько раз), то после каждой нечетной загрузки кроме первой (3-я, 5-я, 7-я и т.д.) происходит переподключение сессии (срабатывает событие OnAfterConnect на компоненте TOraSession). Опытным путем установил, что реконнект идет при обращении к методу Prepare компонента TOraStoredProc. Так как исходников не имею, то не могу понять причину происходящего. При подключении используется Direct. DisconnectedMode отключен.
Re: Восстановление сессии в фоне
Добавлено: Пт 31 июл 2020 13:18
MaximG
Пожалуйста уточните, используете ли Вы DisconnectedMode ? Приведите DDL-скрипт на создание используемой хранимой процедуры и пример кода работы с ней в Вашем проекте
Re: Восстановление сессии в фоне
Добавлено: Пт 31 июл 2020 13:47
yuryleon77
При DisconnectedMode вылетало бы постоянно. Нет, я его не использую.
Re: Восстановление сессии в фоне
Добавлено: Пт 31 июл 2020 13:51
yuryleon77
пример кода в 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;
Re: Восстановление сессии в фоне
Добавлено: Пт 31 июл 2020 13:53
yuryleon77
Код: Выделить всё
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: Восстановление сессии в фоне
Добавлено: Пн 03 авг 2020 08:08
MaximG
Спасибо за предоставленную Вами информацию. Мы проверим работу наших компонентов согласно Вашего описания и сообщим Вам о результатах в самое ближайшее время
Re: Восстановление сессии в фоне
Добавлено: Пт 28 авг 2020 08:41
yuryleon77
Добрый день! Есть какие-либо подвижки по моему вопросу?
Re: Восстановление сессии в фоне
Добавлено: Вт 01 сен 2020 12:18
MaximG
Мы внимательно изучили присланную Вами информацию, но ее оказалось недостаточно для воспроизведения проблемы в нашем окружении. Пожалуйста с помощью формы e-support (
https://www.devart.com/company/contactform.html) пришлите полный исходный код тестового примера, а также DDL-скрипт для создания объектов БД (таблиц, типов и т.д.),
которые необходимы для использования хранимой процедуры import_mvd_dict
Re: Восстановление сессии в фоне
Добавлено: Ср 21 окт 2020 13:47
yuryleon77
Извините за долгий ответ. Поменялся приоритет задач на время.
Посредством формы e-support выслал тестовый пример с описанием необходимых действий.
Re: Восстановление сессии в фоне
Добавлено: Ср 28 окт 2020 16:04
MaximG
Пожалуйста попробуйте отослать Ваш пример еще раз, т.к. к настоящему времени мы не получили на e-support Ваш запрос
Re: Восстановление сессии в фоне
Добавлено: Пт 30 окт 2020 08:06
yuryleon77
Странно отправлял даже дважды. Сейчас отправлю еще раз
Re: Восстановление сессии в фоне
Добавлено: Пт 30 окт 2020 09:14
yuryleon77
MaximG писал(а): ↑Ср 28 окт 2020 16:04
Пожалуйста попробуйте отослать Ваш пример еще раз, т.к. к настоящему времени мы не получили на e-support Ваш запрос
Не могу отослать через e-support. Залогинился, почту не позволяет сменить, но пишет "No such user here"
Как я могу передать вам тестовый пример?
Re: Восстановление сессии в фоне
Добавлено: Пн 02 ноя 2020 12:30
MaximG
По техническим причинам Вы не могли некоторое время воспользоваться нашим сервисом e-support. Сейчас проблема решена, мы получили отправленный Вами пример и приступили к его анализу.
Re: Восстановление сессии в фоне
Добавлено: Вт 03 ноя 2020 08:31
yuryleon77
Отправил еще раз архив с тестовым примером
Re: Восстановление сессии в фоне
Добавлено: Ср 04 ноя 2020 14:50
MaximG
Спасибо за составленный Вами пример. Мы внимательно изучили его работу и убедились, что Вы используете режим DisconnectedMode. Пожалуйста отключите этот режим :
Код: Выделить всё
function TfrmConnectDlg.DoConnect: TModalResult;
begin
...
MainSession.Options.DisconnectedMode := False;
...
end;
и сообщите нам, воспроизводится ли проблема без использования DisconnectedMode