22.03.2005, 17:17 | #1 |
Участник
|
Здравствуйте.
Подскажите, имеет ли значение, в каком порядке указывать SETRANGE и LOCKTABLE? Можно ли вообще говоря, заблокировать не всю таблицу, а только некоторый диапазон записей? А то просто беда с учетом заказов, при учете большого заказа остальные пользователи, работающие с другими заказами, просто напросто висят. В качестве сервера используем MS SQL 2000. |
|
22.03.2005, 17:21 | #2 |
Moderator
|
С SQL все гораздо хуже. На самом деле, код Навижина не оптимизирован для работы с SQL сервером. Если вы почитаете Performance Troubleshooting Guide или Tuning Navision for better performance то поймете, что все не так просто.
|
|
22.03.2005, 17:33 | #3 |
Moderator
|
LOCKTABLE в SQL Server таблицу не лочит вообще. Да и не нужно это.
|
|
23.03.2005, 10:42 | #4 |
Участник
|
Так все таки, почему при учете заказов блокируются ВСЕ заказы, а не только учитываемый? Если в кодеюните 80 после строки SalesLine.LOCKTABLE написать
SalesLine.SETRANGE("Document Type","Document Type"); SalesLine.SETRANGE("Document No.","No."); IF SalesLine.FIND('+') THEN; Это приведет только к блокировке только данного заказа? |
|
23.03.2005, 10:58 | #5 |
Moderator
|
Дело в том, что на SQL версии, оператор FIND БЛОКИРУЕТ ТАБЛИЦУ, а GET и LOCKTABLE - нет.
|
|
23.03.2005, 11:17 | #6 |
Moderator
|
В SQL-версии таблицы никогда не блокируются, блокируются только записи.
Приведенный код SalesLine.LOCKTABLE; SalesLine.SETRANGE("Document Type","Document Type"); SalesLine.SETRANGE("Document No.","No."); IF SalesLine.FIND('+') THEN; заблокирует recordset, состоящий из двух записей - текущей (последней) и предпоследней (обычно блокируется запись сверху и запись снизу). Цитата:
оператор FIND БЛОКИРУЕТ ТАБЛИЦУ, а GET и LOCKTABLE - нет
Rec.LOCKTABLE; Rec.FIND(...) блокирует recordset из трех записей. Код Rec.LOCKTABLE; Rec.GET(...) блокирует текущую запись таблицы Rec |
|
23.03.2005, 11:21 | #7 |
Участник
|
Цитата:
Сообщение от tyrex
В SQL-версии таблицы никогда не блокируются, блокируются только записи.
Только хотелось бы уточнить, что блокировки эскалируются. И если FIND заблокирует достаточно много записей, то СКЛ автоматически поднимет уровень блокировки до страничной и до таблицы. |
|
23.03.2005, 11:29 | #8 |
Moderator
|
Согласен. Правда эскалацию можно отключать.
|
|
23.03.2005, 11:37 | #9 |
Участник
|
ой. не надо бы такие советы давать
это как правка реестра - если не знаешь, то лучше не соваться. если знаешь, то можно делать чудеса. но это отдельная тема. |
|
|
За это сообщение автора поблагодарили: mira (1). |
23.03.2005, 11:39 | #10 |
NavAx
|
Цитата:
Сообщение от mazzy
И если FIND заблокирует достаточно много записей, то СКЛ автоматически поднимет уровень блокировки до страничной и до таблицы.
__________________
"Моей лошадке ядрышком полмордочки снесло..." А.В.Суворов, письма к дочери |
|
23.03.2005, 11:46 | #11 |
Moderator
|
Цитата:
Сообщение от tyrex
В SQL-версии таблицы никогда не блокируются, блокируются только записи.
Приведенный код SalesLine.LOCKTABLE; SalesLine.SETRANGE("Document Type","Document Type"); SalesLine.SETRANGE("Document No.","No."); IF SalesLine.FIND('+') THEN; заблокирует recordset, состоящий из двух записей - текущей (последней) и предпоследней (обычно блокируется запись сверху и запись снизу). Цитата:
оператор FIND БЛОКИРУЕТ ТАБЛИЦУ, а GET и LOCKTABLE - нет
Rec.LOCKTABLE; Rec.FIND(...) блокирует recordset из трех записей. Код Rec.LOCKTABLE; Rec.GET(...) блокирует текущую запись таблицы Rec Важно то, что с базой SQL и родной, Навижин работает по разным принципам, соответственно и написание кода требует ухищрений для корректной работы в обеих вариантах, чего к сожалению не делается. Сейчас одни знакомые энтузиасты работы под SQL активно оптимизируют C/AL код Навижина, результаты неплохие, но объем изменений ужасает. |
|
23.03.2005, 11:52 | #12 |
Участник
|
Значит, исходя из всего вышесказанного, решить проблему с учетом заказов нельзя?
|
|
23.03.2005, 12:10 | #13 |
Moderator
|
Решить можно, но не через механизм блокировок, потому что блокировки и так работают как надо (лочат только диапазон рабочих значений).
Есть идея поставить в цикле побольше COMMIT'ов - тогда после каждого коммита блокировка будет сниматься. Недостаток этого способа - если какая итерация вызовет ошибку, заказ не откатится, а все равно учтется, правда не полностью |
|
23.03.2005, 13:39 | #14 |
Участник
|
Спасибо за ответ. Но COMMIT однозначно не подходит в этой ситуации, надежность все-таки важнее.
|
|
04.04.2005, 18:13 | #15 |
Участник
|
Вот интересная ссылка про sql-локи, может кому интересно будет:
http://www.mbsonline.org/forum/topic.asp?TOPIC_ID=5531 |
|
19.09.2007, 04:55 | #16 |
Участник
|
Интересно, все согласны, что таблицы в SQL Server не блокируются и LOCKTABLE толи не используется, толи непонятно что делает... Между тем C/SIDE Reference Guide утверждает, что :
Цитата:
LOCKTABLE (Record)
Use this function to lock a C/SIDE table to protect it from write transactions that conflict with each other. |
|
19.09.2007, 11:31 | #17 |
Участник
|
|
|
19.09.2007, 12:07 | #18 |
Участник
|
|
|
25.09.2007, 10:31 | #19 |
Участник
|
Не согласен с тем утверждением что locktable работает только в нативной базе. В SQL варианте он тоже работает и блокирует таблицу, если для таблицы вызван locktable, то из другой транзакции можно только читать записи в таблице, любое их изменение упирается в блокировку. Таким образом Locktable для выбранной таблицы поднимает уровень изоляции транзакций до повторяемого четния. То что код учетных CU наполнен операторами locktable только для того чтобы найти последнюю операцию в таблице и на протяжении всего учета таблица будет блокирована, делает реальную многопользовательскую работу невозможной. Именно поэтому висят учеты документов, а иногда nav откровенно пишет ваше действие заблокировано другим пользователем .
|
|
27.09.2007, 14:11 | #20 |
Участник
|
Цитата:
FIND не блокирует таблицу, если текущий уровень изоляции транзакции READUNCOMMITTED. Или в нотации Navision TRANSACTIONTYPE::Browse Аналогично работает и GET. Этот тип изоляции с которым запускается по умолчанию любой код (до первых изменений в базе данных, после этого уровень изоляции увеличивается.) Также с этим уровнем изоляции отображаются некоторые формы, например Фин Журнал и Товарный Журнал. Можно также указать уровень изоляции в свойствах Report'ов (св-во TransactionType). Как правильно заметил Raul, уровень изоляции можно принудительно повысить, применив LOCKTABLE. При этом следующий вызов FIND или GET будет не с хинтом READUNCOMMITTED, а с хинтом UPDLOCK (что заблокирует набор возвращаемых записей). ------ В качестве ускорения учета, мы в компании предприняли много мер, вот некоторые из них, которые приходят на ум:
|
|