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

есть форма на ней контроллы, ну и соответственно курсоров куча

сразу говорю БД сетевая, в буфферизации не сильна пока что еще, и поэтому сохраняю данные примерно так

select table1
append from cursor1.dbf

но вот неурядится, некоторые пользователи наступают примерно на следующие грабли, "Файл используется другим пользователем, Продолжить , Прекратить"

естественно все жмут на продолжить и получается завдоение данных,

могу ли я выше код сохранения переписать как

insert into table1() values(cursor1)
и избавит ли меня в данной ситуации это ?????
29 ноя 05, 12:11    [2119731]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение при сохранении ???  [new]
Недоходящий
Member

Откуда:
Сообщений: 912
попробуй так
select имя_таблы
rlock()
unlock
29 ноя 05, 12:14    [2119748]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение при сохранении ???  [new]
МНастя
Guest
нет так не получится

а вдруг пользователь какой-нибудь будет , я вообщем не знаю уу меня паника может еще чего посоветуете
29 ноя 05, 12:33    [2119901]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение при сохранении ???  [new]
Hel!Riser
Member

Откуда: Нижний Новгород
Сообщений: 972
пользуй обновляемые представления, а не курсоры
29 ноя 05, 12:47    [2119993]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение при сохранении ???  [new]
Igor Korolyov
Member

Откуда: Гомель, Беларусь
Сообщений: 2512

Hi МНастя!

1) по быстрому - вместо append from использовать SCAN по временной таблице,
внутри которого использовать INSERT INTO table1 (поля) VALUES
(cursor1.field1, cursor1.field2,...). Т.е. вставлять по одной таблице за
раз - если будет ошибка блокировки, то не надо будет повторять для уже
вставленных записей. Также не забыть настроить SET REPROCESS - чтоб реже
возникала ошибка 109 при вставке (при значении по умолчанию ошибка не
возникнет, но будет бесконечно долго мучиться, в попытках вставить запись, и
нетерпеливый пользователь сможет по ESC прервать процесс).
2) по правильному - изучать буферизацию и отказываться в перспективе от
работы через временные таблицы. Впрочем там система разрешения конфликтов
совместного доступа по сути аналогична бадуте - т.е. ждём какое то время, и
если неудача - то вопрос пользователю, но дублей никаких не будет - т.к. то
что уже записалось - повторно не будет записываться, а что ещё не успело -
останется в буфере.

Posted via ActualForum NNTP Server 1.3

30 ноя 05, 03:11    [2123424]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение при сохранении ???  [new]
МНастя
Guest
Вот нашла пример в поиске от ВладимираМ,
посмотрите что не так я написала ??

SET MULTILOCKS ON
SET REPROCESS TO 1


LOCAL llSuccess, lcMessageText, laError(1), llOverWrite, llExit
llOverWrite=.F.
llExit=.F.
DO WHILE llExit=.F.

INSERT INTO table1(pole1, pol2);
Values(cursor.pole1, cursor.pole2)
llExit=.T.
BEGIN TRANSACTION
llSuccess=TableUpdate(.T.,m.llOverWrite,"table1")
IF llSuccess=.T.
END TRANSACTION
ELSE
*Немедленный откат изменений
ROLLBACK
* Анализ ошибки
=AERROR(laError)
IF laError[1,1]=1585
lcMessageText = "пока вы вносили изменения "+;
"другой пользователь изменил данные, сохранить?"
IF MessageBox(m.lcMessageBox,'Конфликт обновления',4+32+256)=6
* ответил Да повторяем цикл изменения
llExit=.F.
llOverWrite=.T.
LOOP
ELSE
*Ответил НЕт действия по обновлению
ENDIF
ELSE
lcMessageText = "в процессе обновления произошла ошибка "+;
LTRIM(STR(laError[1,1]))+chr(13)+laError[1,2]
MessageBox(m.lcMessageText,'ошибка при сохранении',0+48)
ENDIF
ENDIF
ENDDO


в данном варианте меня интересует правильно ли я воткунула конструкцию,
точнее туда ли
insert into ...... value().. ??????????
30 ноя 05, 05:32    [2123458]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение при сохранении ???  [new]
МНастя
Guest
Ребяа помогите дельным советом а ?
30 ноя 05, 09:34    [2123744]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение при сохранении ???  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
МНастя

в данном варианте меня интересует правильно ли я воткунула конструкцию,
точнее туда ли
insert into ...... value().. ??????????

Нет. Не правильно.

Чисто формально, в данном коде надо втыкать сразу за командой BEGIN TRANSACTION

Собственно, в данном случае цикл DO WHILE llExit=.F. необходим на случай, если пока пользователь вносил изменения кто-то другой изменил те же самые данные. Но для создания новой записи - это бессмысленно. Т.е. все это можно существенно упростить

* Без этой настройки буферизация невозможна
* т.е. она должна быть сделана раньше и здесь не нужна
* Должна делаться в главном стартовом модуле
SET MULTILOCKS ON 

* Эта настройка уменьшит вероятность конфликта 
* при одновременном создании новых записей
* несколькими пользователями
* Должна делаться в главном стартовом модуле
SET REPROCESS TO 3

LOCAL llSuccess, lcMessageText, laError(1)

BEGIN TRANSACTION

INSERT INTO table1 (pole1, pol2) ;
Values(cursor.pole1, cursor.pole2)

llSuccess=TableUpdate(.T.,.T.,"table1")
IF llSuccess=.T.
	END TRANSACTION
ELSE
	*Немедленный откат изменений
	ROLLBACK
	* Анализ ошибки
	=AERROR(laError)
	lcMessageText = "в процессе обновления произошла ошибка "+;
		LTRIM(STR(laError[1,1]))+chr(13)+laError[1,2]
	MessageBox(m.lcMessageText,'ошибка при сохранении',0+48)
ENDIF

Но это чисто формальное изменение. Не учитывающее особенностей твоей логики (в смысле - логики твоей программы). При этом предполагается, что в момент выполнения данного кода, ты находишся в рабочей области таблицы table1 и эта таблица буферизирована.

Вообще-то, сделай поиск в данном форуме по слову "буферизация". По хорошему, тут надо небольшую лекцию прочитать. Просто сейчас времени нет.
30 ноя 05, 17:00    [2127072]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение при сохранении ???  [new]
FM32YO aka KID
Member

Откуда: Ukraine
Сообщений: 884
здравствуйте Владимир!

ВладимирМ
МНастя

в данном варианте меня интересует правильно ли я воткунула конструкцию,
точнее туда ли
insert into ...... value().. ??????????

Нет. Не правильно.


точно так же я наткнулся на Ваш код.. давно.. и адаптировал его под свои нужды..
причем, на моих опытах (буфферизация ставится 5) получается, что все равно перед BEGIN TRANSACTION или внутри делать модификацию...
затем, в силу навеянного мне убеждения "транзакция должна быть как можно короче" = саму модификацию то есть INSERT-UPDATE-DELETE я вынес за пределы собственно транзакции....
то есть внутри транзакции только TableUpdate,
ну и проверки.. если неудача == роллбэк....

Вот после Вашего утверждения выше.. я засомневался...
1 я неверно делаю
2 или же не имеет особого значения в случае

SET MULTILOCKS ON
=cursorsetprop('buffering', 5, 'Т1')
=cursorsetprop('buffering', 5, 'Т2')

ставить модивикация ВНЕ транзакции, а внутри транзакции только
IF m.llSuccess = .T.
llSuccess = TableUpdate(.T.,m.llIsOtherWrite,'T1')
ENDIF

* Ñáðîñ áóôåðà âòîðîé òàáëèöû
IF m.llSuccess = .T.
llSuccess = TableUpdate(.T.,m.llIsOtherWrite,'T2')
ENDIF
* Ñáðîñ áóôåðà î÷åðåäíûõ òàáëèö
* ....

IF m.llSuccess = .F.
* Íåìåäëåííî ïðåêðàùàåì òðàíçàêöèþ
ROLLBACK
.........
1 дек 05, 10:35    [2129296]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение при сохранении ???  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
FM32YO aka KID
здравствуйте Владимир!

точно так же я наткнулся на Ваш код.. давно.. и адаптировал его под свои нужды..
причем, на моих опытах (буфферизация ставится 5) получается, что все равно перед BEGIN TRANSACTION или внутри делать модификацию...
затем, в силу навеянного мне убеждения "транзакция должна быть как можно короче" = саму модификацию то есть INSERT-UPDATE-DELETE я вынес за пределы собственно транзакции....
то есть внутри транзакции только TableUpdate,
ну и проверки.. если неудача == роллбэк....

Вот после Вашего утверждения выше.. я засомневался...


Еще раз. Я не знаю, какая постановка задачи у Насти. Я исходил из чисто формальной логики данного кода. Смотри что он делает:

DO WHILE ...
INSERT INTO ...
BEGIN TRANSACTION
...
IF ...
	END TRANSACTION
	EXIT
ELSE
	ROLLBACK
ENDIF
ENDDO

Т.е. в данном случае есть риск повторить создание новой записи. По сути, выполнить дважды команду INSERT-SQL. Вот чтобы этого избежать, и необходимо "спрятать" команду INSERT-SQL внутрь транзакции или же вынести команду INSERT-SQL во вне цикла DO WHILE.

К буферизации это не имеет вообще никакого отношения. Просто "формальная" логика.
1 дек 05, 11:40    [2129762]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение при сохранении ???  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
Для Насти.

Во вложенном файле "теоретическая" часть про буферизацию и транзакцию. Т.е. что это вообще такое.

К сообщению приложен файл (Буферизация.txt - 4Kb) cкачать
1 дек 05, 11:59    [2129930]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение при сохранении ???  [new]
FM32YO aka KID
Member

Откуда: Ukraine
Сообщений: 884
ВладимирМ

Т.е. в данном случае есть риск повторить создание новой записи.

да я понял СПАСИБО
1 дек 05, 13:01    [2130372]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение при сохранении ???  [new]
FM32YO aka KID
Member

Откуда: Ukraine
Сообщений: 884
ВладимирМ
[

Т.е. в данном случае есть риск повторить создание новой записи. По сути, выполнить дважды команду INSERT-SQL. Вот чтобы этого избежать, и необходимо "спрятать" команду INSERT-SQL внутрь транзакции


не для флейма.. но я специально пробовал "рвать" связь с БД при такой работе.. ведь транзакция либо вся выполнилась.. либо ничего.. внутри транзакции только сброс буферов.. если хоть один сброс неудачен = откат и все.. то есть не нашел где именно вероятность двойной модификации.....

хотя.. может не так проверял.. я рвал связь после первого ТэйблАпдейта.. или после 2-го и та далее.. всегда откатывало
2 дек 05, 15:40    [2135935]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение при сохранении ???  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
FM32YO aka KID

не для флейма.. но я специально пробовал "рвать" связь с БД при такой работе..

Ты не туда смотрел. Разрыв связи тут вообще не при чем. Если совсем упростить, то исходный (ошибочный) код выглядит так:

DO WHILE ...
	INSERT INTO ...
	IF (удалось сохранить)
		EXIT
	ENDIF
ENDDO

Теперь понятно?

По сути, если первая попытка сохранения неудачная, то пошли на второй заход, который начинается опять с команды INSERT. Но ведь первая команда INSERT отменена не была. Он вне транзакции. Значит, имеем 2 новые записи вместо одной.

Т.е. дается повторная команда INSERT без отмены предыдущей команды INSERT.
2 дек 05, 23:38    [2137816]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение при сохранении ???  [new]
FM32YO aka KID
Member

Откуда: Ukraine
Сообщений: 884
ВладимирМ
FM32YO aka KID

не для флейма.. но я специально пробовал "рвать" связь с БД при такой работе..

Ты не туда смотрел. Разрыв связи тут вообще не при чем.

По сути, если первая попытка сохранения неудачная, то пошли на второй заход, который начинается опять с команды INSERT. Но ведь первая команда INSERT отменена не была. Он вне транзакции. Значит, имеем 2 новые записи вместо одной.

Т.е. дается повторная команда INSERT без отмены предыдущей команды INSERT.


ваше пояснение мне понятно! :-)
То есть инсерт идет в буфер таблицы, а транзакция скидывает буфер собственно в таблицу так?
Иными словами, если не скинула удачно - инсертим в буфер еще раз.. и так далее...
Но разве при искусственном обрыве сети (я же так сказать "поломал" транзакцию), я не должен был получить тот же эффект?
Рву сеть я внутри транзакции, то есть тогда, когда в буффере таблицы уже есть запись... транзакция неудачная и по новой...., ну, разве что эксперимент я проводил давно.. и не помню втыкал ли я сеть сразу после отката.. или же после полного закрытия формы редактирования...
Впредь указанному Вами моменту приделю бОльшее внимание.
Спасибо!
5 дек 05, 09:20    [2140090]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение при сохранении ???  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
FM32YO aka KID
То есть инсерт идет в буфер таблицы, а транзакция скидывает буфер собственно в таблицу так?

Не совсем. Т.е., да, INSERT идет в буфер. Но сброс из буфера в таблицу - это команда TableUpdate().

А транзакция - это некий "глобальный" буфер.

Почитай во вложенном файле несколькими постами выше в этом же топике. Пример с наложением нескольких прозрачных калек вроде бы удачным получился.

FM32YO aka KID
Иными словами, если не скинула удачно - инсертим в буфер еще раз.. и так далее...

Да. Вот здесь правильно.

FM32YO aka KID
Но разве при искусственном обрыве сети (я же так сказать "поломал" транзакцию), я не должен был получить тот же эффект?

Нет. Будет критическая ошибка и программа будет прервана. Не пойдет второй шаг цикла. Куда запись-то вставлять?

Т.е., конечно, транзакцию ты "поломал". Но и вставки не произойдет.
5 дек 05, 18:48    [2142763]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение при сохранении ???  [new]
FM32YO aka KID
Member

Откуда: Ukraine
Сообщений: 884
ВладимирМ

Нет. Будет критическая ошибка и программа будет прервана. Не пойдет второй шаг цикла. Куда запись-то вставлять?

Т.е., конечно, транзакцию ты "поломал". Но и вставки не произойдет.


именно для этого я и проверял. Чтобы убедиться, что ничего не произойдет и ВФП откатит изменения. Назло людям, которые утверждают, что при потере сети ДБФ-ы рухнут :)
6 дек 05, 12:12    [2144472]     Ответить | Цитировать Сообщить модератору
Все форумы / FoxPro, Visual FoxPro Ответить