Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / PowerBuilder Новый топик    Ответить
 Как после disconnect не потерять пользовательские данные?  [new]
Вовик
Member

Откуда: Москва
Сообщений: 196
Добрый День Всем !
Возникла такая проблема. Пользователь получает данные в dw (Retrieve) и начинает их модифицировать. Через некоторое время связь с сервером рвется . Естественно , в dw остаются записи , которые пользователь не успел сохранить.

Вопрос : как не потерять эти данные , которые не успел сохранить пользователь ?

PB 8.0 + PFC + OLE DB (MDAC 2.71) + MS SQL 2000 (SP2)
19 сен 03, 11:42    [345503]     Ответить | Цитировать Сообщить модератору
 Re: Как после disconnect не потерять пользовательские данные?  [new]
Sergey Rijkov
Member

Откуда: Спб
Сообщений: 37
Ну дык, сохрани dw куда нить :) (в psr, например)

-------------
Сергей Рыжков
ЗАО "НПО Балтрос"
http://pbl.narod.ru (PowerBuilder + Oracle)
19 сен 03, 11:53    [345527]     Ответить | Цитировать Сообщить модератору
 Re: Как после disconnect не потерять пользовательские данные?  [new]
ASCRUS
Member

Откуда: МО Электросталь
Сообщений: 5994
Через некоторое время связь с сервером рвется .
А поточнее ? Рвется это как - вообще изчезает до лучших времен или же просто теряется соединение и его можно восстановить ? Если первый вариант, то по ответу Sergey Rijkov, если второй - то надо бы обратно восстановить соединение и работать себе дальше. Ну и в зависимости от варианта конечно надо идеологию приложения продумывать - если изначально подразумевается нестабильное соединение, то и модель программы должна быть ориентированна на отложенную работу с сервером, где соединение с сервером происходит только на время операций приложения с БД и предусмотрен режим сохранения данных локально.
19 сен 03, 12:12    [345561]     Ответить | Цитировать Сообщить модератору
 Re: Как после disconnect не потерять пользовательские данные?  [new]
andy753
Member

Откуда: Moscow
Сообщений: 368
В PSR-е хранить не стоит, места много а толку мало... внутренние буфера не сохраняет... придется потом "ручками" сравнивать данные.

Лучше воспользоваться Get(Set)FullState - выросший из PSR, но храняший все состояние DW. После восстановления коннекта просто восстановиться...
19 сен 03, 12:18    [345573]     Ответить | Цитировать Сообщить модератору
 Re: Как после disconnect не потерять пользовательские данные?  [new]
Вовик
Member

Откуда: Москва
Сообщений: 196
Уточняю : рвется временно ( ошибка типа General Network Error). восстановить , конечноже , можно. видимо это какой-то глюк сети. Происходит не часто. Просто я раньше с этим не сталкивался.

Меня интересует , можно ли сделать в этом случае так , чтобы программа
1.Переприсоединилась к БД
2.Произвела Update ( без Retrieve ) для dw , в котором остались несохраненные данные пользователя после редактирования

и как это примерно должно выглядеть в коде
19 сен 03, 12:21    [345581]     Ответить | Цитировать Сообщить модератору
 Re: Как после disconnect не потерять пользовательские данные?  [new]
Вовик
Member

Откуда: Москва
Сообщений: 196
Правильно я понял , что надо сделать как-то так :
( проверка ошибок опущена )
blob blb_data

dw_1.GetFullState ( blb_data )
SQLCA.of_Connect()
dw_1.event constructor() // там внутри в т.ч. this.of_SetTransObject(SQLCA)dw_1.Retrieve()
dw_1.SetFullState(blb_data )
dw_1.of_Update(TRUE,TRUE)
19 сен 03, 12:39    [345635]     Ответить | Цитировать Сообщить модератору
 Re: Как после disconnect не потерять пользовательские данные?  [new]
andy753
Member

Откуда: Moscow
Сообщений: 368
Можно так сделать, хотя при кратковременных отсоединениях, можно просто восстанавливать коннект. Без Get/SetFullState.

Get/SetFullState удобна при сбросах на файл при долгих дисконнектах...
19 сен 03, 13:00    [345677]     Ответить | Цитировать Сообщить модератору
 Re: Как после disconnect не потерять пользовательские данные?  [new]
Ermak
Member

Откуда: Tomsk
Сообщений: 811
2 Вовик

"dw_1.GetFullState ( blb_data )
SQLCA.of_Connect()
dw_1.event constructor() // там внутри в т.ч. this.of_SetTransObject(SQLCA)dw_1.Retrieve()
dw_1.SetFullState(blb_data )
dw_1.of_Update(TRUE,TRUE)"

Вообще-то update() сама по себе не вызывает retrieve().
Для обработки ошибок БД в dataWindow control есть специальное событие
dberror.
В самом простейшем (проверки убраны) подобного рода обработка может
выглядеть так (для ASA 7.0.4):

if sqldbCode = -85 then

//Communication Error
disconnect using sqlca;
garbageCollect() //Возможно необходимо надо разобраться
connect using sqlca;
this.settransObject(sqlca)
end if
19 сен 03, 14:04    [345832]     Ответить | Цитировать Сообщить модератору
 Re: Как после disconnect не потерять пользовательские данные?  [new]
Вовик
Member

Откуда: Москва
Сообщений: 196
Остановился пока на таком коде , вроде работает

//Object : datawindow
//Event: dberror
.....
//попытка переподключения в случае разрыва соединения
//провайдер - OLE DB for MS SQL 2000 ( используется PFC )
if sqldbcode=11 or sqldbcode=999 then
SQLCA.of_Disconnect()
garbageCollect() //Возможно
IF SQLCA.of_Connect() = -1 THEN
MessageBox('Подключиться Заново не удалось', &
uf_sqlerr_ru(),StopSign!)
ELSE
this.of_SetTransObject(SQLCA)
MessageBox('Соединение с Базой Восстановлено', &
'Повторите Операцию')
END IF
end if

//переназначение объекта транзакции
// ( для других DW после возникновения disconnect и reconnect)
if sqldbcode=-1 then
this.of_SetTransObject(SQLCA)
MessageBox('Внимание', &
'Повторите Операцию')
end if
22 сен 03, 12:43    [347700]     Ответить | Цитировать Сообщить модератору
 Re: Как после disconnect не потерять пользовательские данные?  [new]
ASCRUS
Member

Откуда: МО Электросталь
Сообщений: 5994
Я сделал немного по другому - наследовал transaction, в нем сделал:
Instance variable
public string DBDriverName

Функцию, возвращающую код ошибки потери связи с БД
function ErrorConnectionFailed() return int

choose case DBDriverName
case 'ASA'
return -85
end choose

return 0


Функцию подключения к серверу, возвращающую -1 при ошибке, 0 если подключение уже есть и 1 при удачном подключении
ConnectDb() return int

// New connection
if DBHandle() = 0 then
// Connection to server
Connect using this;

// Error from connection
if SQLDBCode <> 0 then
return -1
end if

return 1
end if

// Test already connection
int i

select 1
into :i
from Dummy;

// Connection is live
if SQLDBCode = 0 then
return 0
end if

// Connection failed and unknow status
if SQLDBCode <> ErrorConnectionFailed() then
return -1
end if

// Clear transaction connection
DisconnectDB()

// Recconect from server
Connect using this;

// Server is not found
if SQLDBCode <> 0 then
return -1
end if

// Reconnect successfull
return 1


Функцию отключения от сервера, возвращающую -1 при ошибке, 0 если уже отключен и 1 при удачном отключении
DisconnectDb() return int

// Server already disconnect
if DBHandle() = 0 then
return 0
end if

// Disconnect
disconnect using this;

// Error
if SQLDBCode <> 0 then
return -1
end if

// Disconnect successfull
return 1


Далее на события DataWindow RetrieveStart и UpdateStart можно спокойненько писать примерно следующий код:

choose case sqlca.ConnectDb()
case 1
SetTransObject( sqlca )
case -1
MessageBox( 'Error', 'Connection lost' )
return 1
end choose

return 0


Все это гарантированно работает, естественно необходимо в проекте указать sqlca на собственный класс transaction, не забыть инициализировать переменную класса DBDriverName и в нее поставить имя драйвера (все никак руки не дойдут сделать его автоматическое получение с ODBC) и расширить функцию ErrorConnectionFailed кодами ошибки потери связи с БД для каждого СУБД.

Чем хорошо, что данный вариант не доводит дело до ошибки в DW, при потере сервака молча пытается восстановить соединение и ругается только в тех случаях, когда это необходимо. Чем плохо, что серваку посылается пусть и безобидный, но лишний запрос, хотя такой способ проверки связи используется во многих провайдерах связи (том же BDE).

Хотя во всяком случае я может быть так и не заморачивался, но мой transaction делался для централизации работы с подключением и даже может рассылать уведомления о подключениях/отключениях всем заинтересованным обьектам приложения, подписавшимся на его события.
22 сен 03, 15:31    [348040]     Ответить | Цитировать Сообщить модератору
Все форумы / PowerBuilder Ответить