powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Сравнение при сохранении ???
17 сообщений из 17, страница 1 из 1
Сравнение при сохранении ???
    #33405399
МНастя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Милые гуру подскажите девушке,

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

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

select table1
append from cursor1.dbf

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

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

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

insert into table1() values(cursor1)
и избавит ли меня в данной ситуации это ?????
...
Рейтинг: 0 / 0
Сравнение при сохранении ???
    #33405408
Недоходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
попробуй так
select имя_таблы
rlock()
unlock
...
Рейтинг: 0 / 0
Сравнение при сохранении ???
    #33405502
МНастя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
нет так не получится

а вдруг пользователь какой-нибудь будет , я вообщем не знаю уу меня паника может еще чего посоветуете
...
Рейтинг: 0 / 0
Сравнение при сохранении ???
    #33405559
Фотография Hel!Riser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
пользуй обновляемые представления, а не курсоры
...
Рейтинг: 0 / 0
Сравнение при сохранении ???
    #33407273
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
...
Рейтинг: 0 / 0
Сравнение при сохранении ???
    #33407298
МНастя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот нашла пример в поиске от ВладимираМ,
посмотрите что не так я написала ??

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().. ??????????
...
Рейтинг: 0 / 0
Сравнение при сохранении ???
    #33407506
МНастя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ребяа помогите дельным советом а ?
...
Рейтинг: 0 / 0
Сравнение при сохранении ???
    #33409175
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МНастя
в данном варианте меня интересует правильно ли я воткунула конструкцию,
точнее туда ли
insert into ...... value().. ??????????
Нет. Не правильно.

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

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

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
* Без этой настройки буферизация невозможна
* т.е. она должна быть сделана раньше и здесь не нужна
* Должна делаться в главном стартовом модуле
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 и эта таблица буферизирована.

Вообще-то, сделай поиск в данном форуме по слову "буферизация". По хорошему, тут надо небольшую лекцию прочитать. Просто сейчас времени нет.
...
Рейтинг: 0 / 0
Сравнение при сохранении ???
    #33410364
Фотография FM32YO aka KID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
здравствуйте Владимир!

ВладимирМ МНастя
в данном варианте меня интересует правильно ли я воткунула конструкцию,
точнее туда ли
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
.........
...
Рейтинг: 0 / 0
Сравнение при сохранении ???
    #33410573
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FM32YO aka KIDздравствуйте Владимир!

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

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


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

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
DO WHILE ...
INSERT INTO ...
BEGIN TRANSACTION
...
IF ...
	END TRANSACTION
	EXIT
ELSE
	ROLLBACK
ENDIF
ENDDO

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

К буферизации это не имеет вообще никакого отношения. Просто "формальная" логика.
...
Рейтинг: 0 / 0
Сравнение при сохранении ???
    #33410640
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для Насти.

Во вложенном файле "теоретическая" часть про буферизацию и транзакцию. Т.е. что это вообще такое.
...
Рейтинг: 0 / 0
Сравнение при сохранении ???
    #33410840
Фотография FM32YO aka KID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМ
Т.е. в данном случае есть риск повторить создание новой записи.
да я понял СПАСИБО
...
Рейтинг: 0 / 0
Сравнение при сохранении ???
    #33414081
Фотография FM32YO aka KID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМ[

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

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

хотя.. может не так проверял.. я рвал связь после первого ТэйблАпдейта.. или после 2-го и та далее.. всегда откатывало
...
Рейтинг: 0 / 0
Сравнение при сохранении ???
    #33415025
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FM32YO aka KID
не для флейма.. но я специально пробовал "рвать" связь с БД при такой работе..
Ты не туда смотрел. Разрыв связи тут вообще не при чем. Если совсем упростить, то исходный (ошибочный) код выглядит так:

Код: plaintext
1.
2.
3.
4.
5.
6.
DO WHILE ...
	INSERT INTO ...
	IF (удалось сохранить)
		EXIT
	ENDIF
ENDDO

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

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

Т.е. дается повторная команда INSERT без отмены предыдущей команды INSERT.
...
Рейтинг: 0 / 0
Сравнение при сохранении ???
    #33416319
Фотография FM32YO aka KID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМ FM32YO aka KID
не для флейма.. но я специально пробовал "рвать" связь с БД при такой работе..
Ты не туда смотрел. Разрыв связи тут вообще не при чем.

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

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

ваше пояснение мне понятно! :-)
То есть инсерт идет в буфер таблицы, а транзакция скидывает буфер собственно в таблицу так?
Иными словами, если не скинула удачно - инсертим в буфер еще раз.. и так далее...
Но разве при искусственном обрыве сети (я же так сказать "поломал" транзакцию), я не должен был получить тот же эффект?
Рву сеть я внутри транзакции, то есть тогда, когда в буффере таблицы уже есть запись... транзакция неудачная и по новой...., ну, разве что эксперимент я проводил давно.. и не помню втыкал ли я сеть сразу после отката.. или же после полного закрытия формы редактирования...
Впредь указанному Вами моменту приделю бОльшее внимание.
Спасибо!
...
Рейтинг: 0 / 0
Сравнение при сохранении ???
    #33418108
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FM32YO aka KIDТо есть инсерт идет в буфер таблицы, а транзакция скидывает буфер собственно в таблицу так?
Не совсем. Т.е., да, INSERT идет в буфер. Но сброс из буфера в таблицу - это команда TableUpdate().

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

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

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

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

Т.е., конечно, транзакцию ты "поломал". Но и вставки не произойдет.
...
Рейтинг: 0 / 0
Сравнение при сохранении ???
    #33419111
Фотография FM32YO aka KID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМ
Нет. Будет критическая ошибка и программа будет прервана. Не пойдет второй шаг цикла. Куда запись-то вставлять?

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

именно для этого я и проверял. Чтобы убедиться, что ничего не произойдет и ВФП откатит изменения. Назло людям, которые утверждают, что при потере сети ДБФ-ы рухнут :)
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Сравнение при сохранении ???
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]