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

Откуда: Россия
Сообщений: 47
У меня следующий вопрос: имеется исходный код
begin transaction
     insert into table1 <что-то> 
     insert into table2 <что-то> 
     replace <что-то> table3
     if <replace не отработал>
           rollback
     endif
end transaction
Я проверяю как отработал replace. Если замены в таблице не было(например она заблокирована другим пользователем), делаю rollback, иначе завершаю транзакцию. Нужно ли мне проверять результаты работы insert, ведь при его работе вроде автоматически блокируется таблица и вставка записи должна происходить 100%, или я не прав?
29 сен 04, 06:19    [994706]     Ответить | Цитировать Сообщить модератору
 Re: Использование транзакций  [new]
SergeyPl
Member

Откуда: Харьков
Сообщений: 287
В Вашем случае не надо. На то она и транзакция, чтобы откатить все операции, которые в нее включены.
29 сен 04, 09:46    [994965]     Ответить | Цитировать Сообщить модератору
 Re: Использование транзакций  [new]
Levran
Member

Откуда: Россия
Сообщений: 47
SergeyPl
В Вашем случае не надо. На то она и транзакция, чтобы откатить все операции, которые в нее включены.


Это понятно, но если replace отработал, а insert нет, я ведь не проверяю результат вставки. Вопрос в том, нужно ли его проверять!
29 сен 04, 09:56    [995008]     Ответить | Цитировать Сообщить модератору
 Re: Использование транзакций  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
В таком контексте нужна проверка корректного завершения каждой команды модификации.

-) INSERT-SQL может НЕ выполнить вставку (много причин), как следствие, REPLACE будет выполнен не туда
-) Собственно REPLACE может НЕ выполнить модификацию (тоже много причин)

Т.е. вопрос даже не в блокировках (хотя тоже есть опасность "мертвых" блокировок, но для этого есть SET REPROCESS), а в корректности выполнения команд.

Обычно для модификации используют буферизацию:

CursorSetProp("Buffering",5,"Table1")
CursorSetProp("Buffering",5,"Table2")
insert into table1 <что-то> 
insert into table2 <что-то> 
replace <что-то> table3
BEGIN TRANSACTION
IF TableUpdate(.T.,.T.,"table1") AND TableUpdate(.T.,.T.,"table2")
	END TRANSACTION
ELSE
	ROOLBACK
	* Анализ причины ошибки по AERROR()
ENDIF

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

Разрешение конфликтов совместного доступа сведено к одному программному узлу (TableUpdate()). А при выполнении собственно команд модификации надо следить только за ошибками корректной модификации данных и уже не обращаешь внимания на проблемы совместного доступа.
29 сен 04, 12:56    [996041]     Ответить | Цитировать Сообщить модератору
 Re: Использование транзакций  [new]
Levran
Member

Откуда: Россия
Сообщений: 47
Тогда наверное имеет смысл включить буферизацию и для третьей таблицы (в которой выполняется replace). В этом случае даже не надо проверять старое значение и новое, чтобы определить выполнился ли replace. Потому что все моменты связанные со сбросом буфера в таблицу берет на себя FoxPro (читай функция TableUpdate()). Так?
29 сен 04, 13:10    [996131]     Ответить | Цитировать Сообщить модератору
 Re: Использование транзакций  [new]
Levran
Member

Откуда: Россия
Сообщений: 47
И вообще, насколько эффективно с точки зрения безопасности и надежности использование транзакции в FoxPro? Не проще ли старым дедовским методом: блокирую все таблицы, вставляю, снимаю блокировку... Понятно, что делать я так не буду, но всё-таки хочется услышать Ваше мнение. Все дело еще в том, что блокировать "надолго" записи у меня возможности (есть свои причины), именно вследствии этой причины я и пришел к использованию транзакции, хотя не очень уверен в обоснованности ее использования.
29 сен 04, 13:15    [996165]     Ответить | Цитировать Сообщить модератору
 Re: Использование транзакций  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
Levran
Тогда наверное имеет смысл включить буферизацию и для третьей таблицы (в которой выполняется replace).

Ну, да, буферизировать надо все таблицы, которые собственно модифицируются. Хотя, возможны исключения из этого правила в конкретной задаче.

Levran
В этом случае даже не надо проверять старое значение и новое, чтобы определить выполнился ли replace. Потому что все моменты связанные со сбросом буфера в таблицу берет на себя FoxPro (читай функция TableUpdate()). Так?

Не совсем. При буферизации нет никакого контроля на значение данных. Проверяется сам факт модификации данных. Но ведь вполне возможно, что пользователь изменил какое-то поле, а потом спохватился и вернул старое значение. При этом, хотя поле было модифицировано, но его значение по сути не изменилось. Если для Вас это имеет принципиальное значение, то такую ситуацию следует дополнительно контролировать.

Levran
И вообще, насколько эффективно с точки зрения безопасности и надежности использование транзакции в FoxPro?

Насколько эффективно и безопасно работать с таблицами DBF? Вопрос того же уровня.

Levran
Не проще ли старым дедовским методом: блокирую все таблицы, вставляю, снимаю блокировку... Понятно, что делать я так не буду, но всё-таки хочется услышать Ваше мнение.

Суть транзакции - это внесение изменений по принципу "Все или ничего". Т.е. либо ВСЕ изменения будут внесены в базу данных, либо не будет внесено НИКАКИХ изменений.

Если жы Вы будете работать без транзакции через блокировку таблиц, то пондобиться самостоятельно писать код по откату внесенных изменений, если, например, в первую таблицу внесли изменения, а во вторую не удалось. Или не изменились часть записей в одной таблице.

Levran
Все дело еще в том, что блокировать "надолго" записи у меня возможности (есть свои причины), именно вследствии этой причины я и пришел к использованию транзакции, хотя не очень уверен в обоснованности ее использования.

Не совсем понял: Вы можете или нет блокировать запись "надолго"?

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

В режиме оптимистической буферизации таблиц (5), один пользователь может сколь угодно долго производить модификацию своего буфера при этом никак не мешая другому пользователю модифицировать те же самые данные.

Блокировка данных будет производится только в момент сброса изменений (по TableUpdate()). В это же время производится и разрешение конфликтов совместного доступа. Если действительно была модификация одних и тех же данных (второй параметр в команде TableUpdate()+AERROR()- код ошибки 1585)
29 сен 04, 14:36    [996523]     Ответить | Цитировать Сообщить модератору
 Re: Использование транзакций  [new]
Igor Korolyov
Member

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

2 ВладимирМ

К сожалению при прямой работе с таблицами даже буферизация не будет
панацеей - ибо часть операций проверки будет сделана ДО сброса буфера.
Именно к вставке это и относится в первую очередь. Среди проводимых
проверок - проверка уникальности индексов.
Введение ещё одного уровня косвенности - локальных представлений - решает
большинство проблем IMHO.

Posted via ActualForum NNTP Server 1.0

29 сен 04, 23:40    [998157]     Ответить | Цитировать Сообщить модератору
 Re: Использование транзакций  [new]
Levran
Member

Откуда: Россия
Сообщений: 47
ВладимирМ

Обычно для модификации используют буферизацию:

Далее вы пишите, что нужно включить оптимистическую блокировку таблиц.
CursorSetProp("Buffering",5,"Table2")
Объясните пожалуйста, как будет работать транзакция, если я открою таблицу с пессимистической блокировкой?
CursorSetProp("Buffering",4,"Table2")
1 окт 04, 07:32    [1000954]     Ответить | Цитировать Сообщить модератору
 Re: Использование транзакций  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
Буферизация и транзакция - это 2 разных процесса. Выбор типа буферизации никак не может повлиять на логику работы транзакции.

Особенность транзакции заключается в том, что если внутри нее сделана любая блокировка данных, то эта блокировка не может быть снята пока не будет так или иначе завершена транзакция.

Отличие оптимистической буферизации от пессимистической заключается в моменте установки блокировки на редактируемые данные.

При оптимистической буферизации в процессе редактирования буфера данные остаются НЕ заблокированными. Блокировка осуществляется только в момент сброса буфера (например, по команде TableUpdate()).

Как следствие, одни и те же данные в режиме оптмистической буферизации одновременно могут редактировать несколько пользователей. "Разбор полетов", т.е. чьи же изменения следует записать в базу данных осуществляется в момент попытки сброса буфера.

При пессимистической буферизации данные блокируются в момент начала их модификации. Блокировка снимается в момент сброса буфера.

Как следствие, если один пользователь начал редактирование данных, то другой уже не сможет начать редактирование пока первый пользователь их не закончит. Однако попытка второго пользователя начать модификацию вызовет сообщение об ошибке (108 или 109), которую необходимо будет перехватить и обработать.

По возможности, не желательно использовать пессимистическую буферизацию. И вообще, желательно свести время блокировки данных к возможному минимуму.

Если опустить чисто психологическую проблему (пользователь желает редактировать, а его не пускают), то проблема в том, что блокировка данных - это технически опасный момент. В том смысле, что сбой питания или обрыв соединения в этот момент может привести к порче структуры таблицы (но может и НЕ привести. Как повезет). Более опасным в этом смысле является только прямое редактирование данных неопределенно долгое время.
1 окт 04, 09:27    [1001213]     Ответить | Цитировать Сообщить модератору
 Re: Использование транзакций  [new]
&&&&&
Guest
2 ВЛАДИМИРМ

==Как следствие, одни и те же данные в режиме оптмистической буферизации ==одновременно могут редактировать несколько пользователей. "Разбор ==полетов", т.е. чьи же изменения следует записать в базу данных ==осуществляется в момент попытки сброса буфера.

А НЕ ПОДСКАЖЕТЕ ЛИ ПО-КОНКРЕТНЕЙ НАСЧЕТ РАЗБОРКИ ПОЛЕТОВ...
ИМХО - если НЕ разбирать их - то в базу запишутся данные того, кто последний нажал СОХРАНИТЬ...
Но ведь это порой не хорошо... как быть тогда?
1 окт 04, 09:31    [1001224]     Ответить | Цитировать Сообщить модератору
 Re: Использование транзакций  [new]
ВладимирМ
Member

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

А НЕ ПОДСКАЖЕТЕ ЛИ ПО-КОНКРЕТНЕЙ НАСЧЕТ РАЗБОРКИ ПОЛЕТОВ...
ИМХО - если НЕ разбирать их - то в базу запишутся данные того, кто последний нажал СОХРАНИТЬ...
Но ведь это порой не хорошо... как быть тогда?

Посмотрите парой постов выше:

IF TableUpdate(.T.,.F.)=.F.
	LOCAL laError(1)
	=AERROR(laError)
	IF laError[1,1]=1585
		* Пока Вы редактировали данные другой пользователь 
		* изменил те же самые данные. Писать поверх?

		* Если решили писать поверх:
		TableUpdate(.T.,.T.)
	ENDIF
ENDIF

Это, опять же, только схема. Если сброс буфера окружен транзакцией, то перед запросом к пользователю надо отменить транзакцию (ROOLBACK) и заново начать весь процесс, если пользователь захотел писать поверх изменений другим пользователем.

Ни в коем случае нельзя оставлять "подвешенную" тарнзакцию на момент ожидания реакции пользователя!

Впрочем, прежде чем писать такую обработку, неплохо бы оценить, насколько в конкретной задаче запись поверх изменений другого пользователя будет критична.
1 окт 04, 09:44    [1001262]     Ответить | Цитировать Сообщить модератору
 Re: Использование транзакций  [new]
Levran
Member

Откуда: Россия
Сообщений: 47
Может подскажите, где хранится буфер транзакции. Локально? В dbc? И где найти документальное подтверждение этому...
1 окт 04, 10:01    [1001310]     Ответить | Цитировать Сообщить модератору
 Re: Использование транзакций  [new]
XAndy
Member

Откуда: Киев
Сообщений: 326
автор
Может подскажите, где хранится буфер транзакции. Локально? В dbc? И где найти документальное подтверждение этому...


В dbc. Там есть запись ObjectName="TransactionLog", в одном из memo-полей этой записи ИМХО и хранится журнал транзакций.
1 окт 04, 10:51    [1001537]     Ответить | Цитировать Сообщить модератору
 Re: Использование транзакций  [new]
Igor Korolyov
Member

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

2 XAndy

Я сомневаюсь что там что-то хранится, и тем более что фокс реально ведёт
полноценный "лог транзакции". Я думаю что тут всё попроще будет. Как доводы:
Открытие dbc в режиме NOUPDATE не мешает транзакции, Просмотр этого поля dbc
в другой сессии во время специально подвешенной транзакции ничего не
показывает, равно как и просмотр в той-же сессии (USE database.dbc SHARED
AGAIN IN 0 ALIAS tmpDB), введение в VFP9 транзакций для free-таблиц.
Как я понимаю вся информация вплоть до ROLLBACK/END TRANSACTION хранится
исключительно в памяти фокса, и при сбоях просто пропадает.
Вообще транзакции фокса существенно отличаются от транзакций других
СУБД. Это факт.

Posted via ActualForum NNTP Server 1.0

2 окт 04, 02:16    [1003764]     Ответить | Цитировать Сообщить модератору
 Re: Использование транзакций  [new]
Sergey Ch
Member

Откуда: Благовещенск
Сообщений: 8873
Вообще-то Ken Levy заявил, что в VFP пока не планируется вводить полноценную базу данных в качестве источника данных. Но если кому надо - то есть MS SQL Server (2Gb бесплатно - остальное за деньги ) Так что естественно транзакции в VFP не совсем надежны.

Хотя все познается в сравнении - выдерните провод питания из сервера SQL при большой загрузке - и Вы поймете, что нет в жизни совершенства Но это уже в другой раздел этого уважаемого форума - могу подсказать ключевые слова для поиска - "База упала/слетела/исчез transaction log e.t.c."...
2 окт 04, 12:27    [1003927]     Ответить | Цитировать Сообщить модератору
 Re: Использование транзакций  [new]
Levran
Member

Откуда: Россия
Сообщений: 47
В умной книжке Рода Пэддока "VFP 6. Разработка корпоративных приложений" написано
Пэддок

...VFP использует протокол транзакций, но не создаёт для этого отдельной таблицы...

Может кто подскажет, можно ли сохранить этот протокол, или хотя бы посмотреть его в момент выполнения....
4 окт 04, 13:35    [1006121]     Ответить | Цитировать Сообщить модератору
 Re: Использование транзакций  [new]
Igor Korolyov
Member

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

2 Levran

Штатных средств точно нету, про недокументированные я ничего не знаю. В
общем маловероятно что ты найдёшь где-то решение. Скорее всего для этого
надо залазить в память фокса, ковыряться в его внутренних структурах, и т.п.

Posted via ActualForum NNTP Server 1.0

4 окт 04, 23:58    [1007933]     Ответить | Цитировать Сообщить модератору
Все форумы / FoxPro, Visual FoxPro Ответить