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

Код: 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.
USE table1 IN  0  SHARED
USE table2 IN  0  SHARED
USE table3 IN  0  SHARED
IF  RLOCK('0', 'table1') AND RLOCK('0', 'table2')
    LOCAL ошибка
    ошибка = .F.
    ON ERROR ошибка = .T.    
    BEGIN TRANSACTION
    INSERT INTO table1......
    INSERT INTO table2......

    FOR <условие цикла>
        SELECT table3
        REPLACE ALL field1 WITH MyVar FOR <условие>
    ENDFOR

    IF ошибка
        ROLLBACK
        UNLOCK IN table2
        UNLOCK IN table1
    ELSE
        END TRANSACTION	
        UNLOCK IN table2
        UNLOCK IN table1
    ENDIF
ELSE
    UNLOCK IN table2
    UNLOCK IN table1
ENDIF
...
Рейтинг: 0 / 0
Насколько грамотна такая конструкция?
    #34599219
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В принципе, ничего особо криминального нет, кроме того, что нет и особого смысла в предварительных явных блокировках. А тормозит, скорее всего, команда REPLACE FOR ...

Дело в том, что подобная команда накладывает блокировку на ВСЮ таблицу. Без исключения. Вне зависимости от того, попадают записи в FOR-условие или нет. А поскольку она у тебя внутри транзакции, то и висеть эта блокировка будет до окончании транзакции.

Либо замени команду REPLACE FOR... на команду UPDATE-SQL, либо делай REPLACE в цикле, по одной записи за раз

Код: plaintext
1.
2.
3.
select table3
SCAN FOR <условие>
    REPLACE field1 WITH MyVar 
ENDSCAN

Одиночная команда REPLACE без указания SCOPE и (или) опций FOR, WHILE блокирует только одну текущую запись. Ту, которую и изменяет.

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

А вообще-то, лично я сделал бы сначала все модификации в буфере таблиц, а затем уже через TableUpdate() осуществлял бы сброс. Можно и в транзакции, еси необходимо.
...
Рейтинг: 0 / 0
Насколько грамотна такая конструкция?
    #34599997
но REPLACE выполняется к третьей таблице, которую я явно не блокирую....

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

да, и REPLACE у меня всё-таки без FOR.... замена происходит по одной записи....

и если быть более точным, то второй инсёрт у меня выполняется в цикле
примерно так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
BEGIN TRANSACTION
INSERT INTO table1.....
FOR <перебор элементов массива>
    INSERT INTO table2......
    SELECT table3
    LOCATE FOR <условие>
    IF FOUND()
        REPLACE <поле> WITH <значение>   
    ENDIF
NEXT
END TRANSACTION
...
Рейтинг: 0 / 0
Насколько грамотна такая конструкция?
    #34600172
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Старайся избегать использования FOR для больших таблиц лучше сделать индекс использовать SEEK и WHILE. Вместо REPLACE FOR (кстати ALL тут лишнее)
Код: plaintext
1.
2.
set order to ...
if seek(MyValue)
replace while CurrentValue = MyValue ...
Единственное ограничение - нельзя менять значения полей участвующих в индексе

ну и LOCATE меняй на SEEK

а чтобы точно узнать где тормоз - в дебагере запускаешь Tools->Coverage logging..., указываешь файл с логом, затем выполняешь свой код, останавливаешь отладчик, а потом смотришь на итого в IDE через Tools->Coverage Profiler
Там и увидишь сколько раз и сколько времени выполнялась каждая строчка в твоем коде
...
Рейтинг: 0 / 0
Насколько грамотна такая конструкция?
    #34600192
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И на счет этого:
Код: plaintext
ON ERROR ошибка = .T.
очень нехорошее использование:
1. Может возникнуть ситуация что код зациклится
2. Бессмысленно продолжать выполнение кода, если произошла ошибка
3. Ты никогда не узнаешь что в коде есть ошибка не связанная с блокировками
4. Надо не забыть вернуть на место прежний обработчик ошибок

Лучше использовать TRY ... CATCH и обрабатывать только те ошибки, которые ожидаешь, а не все подряд. Всегда надо исходить из того что в коде остались ошибки, которые вскроются в будущем.
...
Рейтинг: 0 / 0
Насколько грамотна такая конструкция?
    #34636120
Фотография MaestroEv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну на мой взгляд - ужасно...

Нельзя в одном модуле смешивать все подряд...
Ну как правило.. table1 table2 и пр.. этож ж ведь таблицы которые описывают что -то.. Значит так..
If OpenDbf("Суть таблицы 1")
&&& ну например "товары" или "клинты" и т.п. А уже OpenDbf -свяжет суть с таблицей
индексами - местами расположения и вообще возможностью открыть..
if OpenDbf("Суть таблицы 2")
if OpenDbf("Суть таблицы 3")
If Make("СУТЬ таблицы 1","состояние 2") &&& где состояние 2 - одно из реальных состояний в которых может находиться таблица 1..

Ну и все в таком виде... А уже там где -то в Make надо применять Insert SQL и подобные команды..
И никогда не делать Insert в "Сущность таблицы 1" иначе как через Make... ну надеюсь понятно...

А то все в кучу... У программы... есть.. должны быть уровни... слои... Нельзя из одного слоя к другому обращаться... даже если хочется... Иначе надежность - пещерная...
Грубо говоря .. у вас автомобиль.. руль.. педали... красиво... и провода вместо ключа .. красный и синий... а должен быть замок зажигания... сверху проводов..

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


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