Переключение на Главную Страницу Страницы: [1] 2 3 4 ОтправитьПечать
Очень популярная тема (более 25 ответов) Справочник плюс. Прямая запись и чтение в справочники 1С 7.7 (число прочтений - 27882 )
an2
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 43
Зарегистрирован: 23. Марта 2012
Справочник плюс. Прямая запись и чтение в справочники 1С 7.7
25. Мая 2012 :: 10:02
Печать  
Чтоб избавиться от дедлоков (точнее от вылетов, которые с дедлоками связаны) намалевал КОП наследник от Справочник-а.
Главное назначение - правильная запись и чтение.


Что дает этот класс:

1. Запись выполняется правильно: без монопольных блокировок таблиц. Это дает возможность выполнять запись параллельно.

По моим наблюдениям  подавляющая часть вылетов 1С 7.7 на SQL базах связано с desdlock-ами и так называемыми "недопустимыми состояниями курсора" таблиц справочников и таблицы констант. (Почему-то на документах такого добра нет).

Любопытно еще и то, MS SQL, по моим наблюдениям, лучше обрабатывает стандартную блокировку (updlock на уровне записей). У меня не получалось добиться desdlock при попытках блокировать из разных транзакций одну и ту же запись. Первая транзакция блокирует, а все остальные мирно ждут своей очереди. То есть при правильной записи добиться desdlock-а не простая задача.

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

3. Открытая форма элемента не блокирует запись.

4. Пишется только то, что изменил пользователь. То есть пользователь мог открыть форму элемента, поменять там один реквизит, пока форма открыта, программно могло поменяться 15 реквизитов. Но когда пользователь нажмет ОК. Запишется только один, изменненый им, реквизит.

5. Следствие пункта 4: Легко отслеживать и, при необходимости, фиксировать, что менял пользователь.

6. Следствие отсутствия монопольных блокировок: Можно ПРАВИЛЬНО читать данные, а не так как у 7.7: nolock без транзакции и tablockX в транзакции (и то и другое Юрский период). Правильно читая (не нолоком, а с ЛЮБЫМ другим хинтом) вы никогда не столкнетесь с ситуацией, когда элемент справочника есть, но в один прекрасный момент 1с его почему-то не увидел. (Что интересно на документах я такой фичи не наблюдал).

7. Нет нужды в перехвате событий справочника как объекта. Все события у вас уже под руками.

8. Со временем хочу заменить все штатные (курсорные) выборки на запросы. И скорость выше и нагрузка не систему ниже и встреч с "недопустимыми состояниями курсора" не будет.

Как это работает:

В глобальнике еще до загрузки 1CPP.dll проверяется и при необходимости пересоздается файл описания классов с именами справочников. Далее для получения агрегатного объъекта вместо спр = СоздатьОбъект("Справочник.Вид"); пишем спр = СоздатьОбъект("Справочник.Вид.Б");

В ФОРМАХ: События формы перехватываются Классом ПерехватчикГК (Это класс выполняющий роль фабрики событий группового контекста) и направляются в класс ПерехватчикГК.Справочник - класс обслуживающий прямую запись во всех формах справочников (и в формах списков и в формах элементов и в формах групп).


ТРЕБОВАНИЯ и ОГРАНИЧЕНИЯ:

1. FormEx.dll, 1CPP.dll

2. УРБД не поддержано. Если разработка заинтересовала готов поддержать.

3. НЕДОПУСТИМО, в форме элемента или списка справочника использовался метод Формы Записать() - На методе записать() происходит выход 1с-а в астрал. (Речь идет не о спр.Записать() для созданного объекта, а о методе формы, который записывает ТекущийЭлемент() формы).

4. Если используется событие ФормаПослеЗаписи() в начале Метода НЕОБХОДИМО вставить: СтатусВозврата(1);

это связано с особенностью реализации этого метода: при СтатусеВозврата() = 0 в ПриЗаписи() этот метод уже на входе имеет СтатусВозврата() = 0

5. ТекущийЭлемент() в форме необходимо получать через глобальную функцию

глТекущийЭлементФормы(Контекст)

6. Если запись выполняется без закрытия формы, то После записи форма закрывается, а затем открывается. Так проще.

7. Наверно нужно причислить к недостаткам: Фабрика событий не стандартный класс фабрики событий с форума 1C++. Ну не нравится мне передача параметров через список. Сначала укладываем, потом разукладываем это ведь время.

Состав архива:

Каталог тестовой базы со всем необходимым внутри + Выгрузка этой же базы.

Интересно услышать мнения.

Публикация на инфостарте: infostart.ru/public/137108/
« Последняя редакция: 25. Мая 2012 :: 18:25 - an2 »  

spravochnikplyus.rar ( 1128 KB | Загрузки )
Наверх
 
IP записан
 
an2
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 43
Зарегистрирован: 23. Марта 2012
Re: Справочник плюс. Прямая запись и чтение в справочники 1С 7.7
Ответ #1 - 29. Мая 2012 :: 16:11
Печать  
Если пригодилось можно плюсануть на инфостарте.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Справочник плюс. Прямая запись и чтение в справочники 1С 7.7
Ответ #2 - 29. Мая 2012 :: 17:13
Печать  
пункт 4 ( понятно что используешь оптимистис подход )
открыл форму пользователь А
открыл форму пользователь Б
пользователь А поменял реквизиты 1 и 2
пользователь Б поменял реквизиты 1 и 3
пользователь Б сохранил
пользователь А сохранил

Получили "нечто" что никто не записывал.

Учитываешь ли ты в subj что могут быть отборы ??

Блокировки точнее взаимоблокоровки получал на справочнике когда снимал стандартную блокировку  и несколько пользователей
создавали один и тот же прайс лист с количеством строк более 3000.


Если надо могу объяснить зачем именно 1с блокирует на запись справочники когда идет проведение документа.


Как бы цель непонятна.


Цитата:
8. Со временем хочу заменить все штатные (курсорные) выборки на запросы. И скорость выше и нагрузка не систему ниже и встреч с "недопустимыми состояниями курсора" не будет.

смотри поакуратней
искать ошибки в паралельно работающих сесcиях ( нет повторяемости ошибки)
очень тяжело и неблагодарно.
Что именно выиграешь неизвестно.
  
Наверх
 
IP записан
 
an2
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 43
Зарегистрирован: 23. Марта 2012
Re: Справочник плюс. Прямая запись и чтение в справочники 1С 7.7
Ответ #3 - 30. Мая 2012 :: 06:45
Печать  
1.
Z1 писал(а) 29. Мая 2012 :: 17:13:
пункт 4 ( понятно что используешь оптимистис подход )
открыл форму пользователь А
открыл форму пользователь Б
пользователь А поменял реквизиты 1 и 2
пользователь Б поменял реквизиты 1 и 3
пользователь Б сохранил
пользователь А сохранил
Получили "нечто" что никто не записывал.

Про то, что несколько пользователей могут открыть на редактирование 1 форму я не писал. 1С 7.7 такого не позволяет, и я в этом направлении ничего не делал.
Чтоб добиться такой возможности, Необходимо открывать не стандартную форму элемента, а стороннюю. Или как-то извращаться Формексом. (Отвечаю и самому интересно стало можно ли так извернуться, чтоб не делая дополнительных форм получить возможность множественного открытия формы одного элемента).
Я писал про то, что пока форма открыта, 1с блокирует программную запись открытого элемента. А это я считаю злом.

2.
Z1 писал(а) 29. Мая 2012 :: 17:13:
Учитываешь ли ты в subj что могут быть отборы ??

Я что-то пропустил ???? О чем идет речь? Озадачен

3.
Z1 писал(а) 29. Мая 2012 :: 17:13:
Если надо могу объяснить зачем именно 1с блокирует на запись справочники когда идет проведение документа.

Я так понимаю речь идет не о всех справочниках, а только о тех в которые идет запись при проведении?
Если только о таких, то проведение здесь не причем. У 1с 7.7 один механизм блокировок справочников на все случаи. Механизм такой: Если открыта транзакция, то чтение выполняем с хинтом TablokX (монопольная блокировка таблицы) это все. Смысла в этом не вижу вообще никакого. Зачем блокировать всю таблицу, когда мы не пишем во всю таблицу??.
Более того блокируются таблицы не только тех справочников, в которые пишем. Блокируются таблицы всех справочников, которые читались при проведении. Не просто не вижу смысла. А я б сказал "Верх маразма".
Надо блокировать? - блокируй необходимые записи. Зачем вся таблица?
Я понимаю, что при желании можно найти смысл и в монопольной блокировке всей базы при проведении документа.
Но реальность - не сферический конь в вакууме. Во всем нужна разумная достаточность.

4.
Z1 писал(а) 29. Мая 2012 :: 17:13:
Как бы цель непонятна.

Про цель я писал в самом начале. Вылечить от вылетов 1с. А вылеты по большей части связаны с монопольными блокировками таблиц справочников и таблицы констант. Свои базы от вылетов я вылечил.

5.
Z1 писал(а) 29. Мая 2012 :: 17:13:
Цитата:
8. Со временем хочу заменить все штатные (курсорные) выборки на запросы. И скорость выше и нагрузка не систему ниже и встреч с "недопустимыми состояниями курсора" не будет.

смотри поакуратней
искать ошибки в паралельно работающих сесcиях ( нет повторяемости ошибки)
очень тяжело и неблагодарно.
Что именно выиграешь неизвестно.

Опять не понял. Озадачен
  
Наверх
 
IP записан
 
an2
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 43
Зарегистрирован: 23. Марта 2012
Re: Справочник плюс. Прямая запись и чтение в справочники 1С 7.7
Ответ #4 - 30. Мая 2012 :: 07:44
Печать  
Цитата:
Как бы цель непонятна.

Про цель я уже написал. Могу только про следствия добавить:
- Скорость записи в среднем в 2 раза выше. Как по мне - это неплохой бонус. Правда я, ожидал большего выигрыша.
- Все действия выполняются подготовленными запросами. Поэтому нагрузка на процессор SQL сервера немного ниже (ну и нагрузка на память немного вышеУлыбка )
- Апдейты в больших таблцах мирно параллельно выполняются в любых объемах.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Справочник плюс. Прямая запись и чтение в справочники 1С 7.7
Ответ #5 - 30. Мая 2012 :: 08:37
Печать  
2 отборы справочника пишутся и в другую таблицу.
аналогично и периодика.

3 при проведении блокировка на справочники идет потому что 1с универсальная система
и 1с не может знать используются или нет справочники или реквизиты справочников при проведении
по моему блокировка  в модуле проведения идет на справочники измерения в регистрах +
на справочники которые попадают в запрос = СоздатьОбъект("Запрос");

4 Вылеты из-за блокировок справочников такого вообще не встречал ни разу.
если снимишь блокировки со справочников то при большой нагрузке на них можешь получить что при паралельном создании
получаются перекресные объекты со всеми вытекающими
пользователь 1 создает обект A ему возвращается объект B
пользователь 2 создает обект B ему возвращается объект A

5 имелось ввиду что если снимаешь стандартные блокировки
то все равно нужен свой механизм блокировок учитывающий особенности конфигурации.
без блокировок совсем -нельзя. Обоснование
если  нет нагрузки тогда зачем их снимать если ,ольшая нагрузка без блокировок как минимум получишь неправильные
итоги (rg)
  
Наверх
 
IP записан
 
an2
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 43
Зарегистрирован: 23. Марта 2012
Re: Справочник плюс. Прямая запись и чтение в справочники 1С 7.7
Ответ #6 - 30. Мая 2012 :: 09:40
Печать  
2. У справочников в 7.7 нет служебных таблиц отборов. А периодические реквизиты я пишу, и делаю это с правильными блокировками.

3 По поводу что именно блокируется при проведении спорить не буду. Глубоко не копал.

4 Большие базы, большие справочники: вылеты при записи на раз два.
Цитата:
получаются перекресные объекты со всеми вытекающими
пользователь 1 создает обект A ему возвращается объект B
пользователь 2 создает обект B ему возвращается объект A

Такого не встречал. Может такое и возможно.
Могу только сказать, что при правильном использовании моего класса таке невозможно.
Почему?
Потому, что при записи нового элемента новый ID ему даю я самостоятельно. Делается это в таком порядке:

1 Открывается транзакция.
2 читается из базы MAX(ID) справочника с хинтом updlock.
3 Нашему новому элементу присваивается ID+1 (естественно с основанием 36)
4 Элемент записывается.
5 Транзакция закрывается.

Это все никаких чудес и бубнов.

Хинт updlock это и есть правильная блокировка (в данном случае).
А все пять пунктов вместе это: Правильное чтение и правильная запись для MS SQL 2000.

4
Цитата:
Если снимишь блокировки со справочников


Я не убираю блокировки. Я даю управление блокировками.
В самом начале я указал назначение класса:
Главное назначение - правильная запись и чтение.

Что такое Правильное чтение? Это, когда чтением данных мы управляем подсказками (хинтами).

- Допустим сейчас мы формируем оперативный отчет. Достоверность данных нас не интересует. Главное скорость получения.
Читаем с хинтом (nolock). Что-то прочитаем дважды, что-то ни разу, что-то прочитаем криво (наполовину одни данные на половину другие)
- все х#рня плюс минус пол минллиона нас не интересует.
(Для этой задачи класс не подходит для массового получения данных нужно использовать запросы.)

- Следующая история: в модуле проведения читаем реквизиты товара.
Считаю, что лучше читать с хинтом serializable - гарантирует, что в момент чтения данные не меняются. И большего не нужно.
Не нужно блокировать ни таблицу товаров до окончания транзакции, ни читаемую запись до окончания транзакции.
Если б наш учет нуждался в такой точности, то мы б уже на выходные летали в соседние галлактики.

- История 3: Программно ищем элемент справочника с кодом "0015" если не нашли - создаем.
И вот тут начинается интересное. Попросите 1с найти элемент по коду. Что она сделает?
Правильно - найдет его с хинтом nolock. Что нам гарантирует хинт nolock? - НИЧЕГО.
Например сейчас кто-то выполняет запись элемента именно с таким кодом.
Как вариант добрый 1с возвращет 0 (нет такого элемента). И такой ответ отнюдь не моя фантазия.
Мы, по простоте душевной, верим и создаем новый. Чудно если на Код стоит проверка уникальности
- тогда мы получим исключение, а если не стоит - получим дубликат.
Почему получим исключение в первом случае? Потому, что хитрый 1с знает как проверить уникальность кода при записи.
(А я, когда мне надо было давать свои уникальные номера справочникам не знал. И никак не мог понять почему же у меня столько дубликатов получается).

Как это ДОЛЖНО БЫЛО БЫТЬ (что класс и позволяет делать):
Измененный метод  НайтиПоКоду() имеет два дополнительных параметра. Синтаксис:
НайтиПоКоду(Код,ФлагПоиска,Хинт=0,ТолькоСсылку=0)
  Хинт - способ чтения. Можно указать строкой, можно числом. Строка - все, что съест ms SQL; Число: наиболее полезные подсказки: 0 - nolock, 1 - readcommitted, 2 - serializable, 3 - updlock
  ТолькоСсылку значения: 0 - прочитать все реквизиты (по умолчанию); 1 - только найти ссылку (ТекущийЭлемент())  

спр = СоздатьОбъект("Справочник.УникальныйПоКоду.Б");
// Ищем ссылку с хинтом 2 (serializable) (гарантированно записанные и никем не изменяемые в момент чтения данные)
// ТолькоСсылку = 1 (допустим нам не нужны реквизиты. Нужна только ссылка на элемент)
Если спр.НайтиПоКоду("0015",0,2,1) = 0 Тогда
   // Если не нашли то его ДЕЙСТВИТЕЛЬНО НЕТ.
   // Далее если хочется гарантированно правильных данных придется воспользоваться транзакцией
   // Других вариантов не бывает
   // Если Не нашли: открываем транзакцию и читаем с хинтом 3 (updlock) - чтение, дающее гарантию, что до завершения
   // транзакции никто другой не сможет записать анналогичные данные. (Данные соответсвующие нашим условиям).
   НачатьТранзакцию();
   Если спр.НайтиПоКоду("0015",0,3,1) = 0 Тогда
       // Если и теперь не нашли, то со спокойной совестью пишем гарантия уникальности = 100%
       спр.Новый();
       спр.Код= "0015";
       спр.Записать();
   КонецЕсли;
   ЗафиксироватьТранзакцию();
КонецЕсли;  

Класс не снимает блокировки. Класс их ДОБАВЛЯЕТ.
« Последняя редакция: 30. Мая 2012 :: 16:03 - an2 »  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Справочник плюс. Прямая запись и чтение в справочники 1С 7.7
Ответ #7 - 30. Мая 2012 :: 10:22
Печать  
2
Цитата:
У справочников в 7.7 нет служебных таблиц отборов.

Доп таблица для отборов по значениям реквизитов справочника _1SCRDOC
и при изменении элемента справочника ее тоже надо учитывать.

4 Начинаю понимать.
Постотри мою статью быстрые справочники http://www.1cpp.ru/forum/YaBB.pl?num=1152519272

Но я как бы исхожу только чтение. Ты же говоришь и про запись. м сразу все становиться гораздо сложнее.

Ну и у моей базе почти все справочники можно считать "статическими".
по сравнению с другими объектами они практически не меняются
и исходя из этого для меня важно только чтение а
оптимизацию чтения можно делать за счет передачи не всех атрибутов  строки базы а только необходимых.
  
Наверх
 
IP записан
 
an2
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 43
Зарегистрирован: 23. Марта 2012
Re: Справочник плюс. Прямая запись и чтение в справочники 1С 7.7
Ответ #8 - 30. Мая 2012 :: 16:37
Печать  
Z1 писал(а) 30. Мая 2012 :: 10:22:
2
Доп таблица для отборов по значениям реквизитов справочника _1SCRDOC
и при изменении элемента справочника ее тоже надо учитывать.

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

Проверено профайлером.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Справочник плюс. Прямая запись и чтение в справочники 1С 7.7
Ответ #9 - 30. Мая 2012 :: 17:14
Печать  
an2 писал(а) 30. Мая 2012 :: 16:37:
Z1 писал(а) 30. Мая 2012 :: 10:22:
2
Доп таблица для отборов по значениям реквизитов справочника _1SCRDOC
и при изменении элемента справочника ее тоже надо учитывать.

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

Проверено профайлером.

ну да не использует.
это что-то я заработался.
  
Наверх
 
IP записан
 
aou1c
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 183
Местоположение: Екатеринбург
Зарегистрирован: 29. Мая 2006
Пол: Мужской
Re: Справочник плюс. Прямая запись и чтение в справочники 1С 7.7
Ответ #10 - 31. Мая 2012 :: 12:36
Печать  
Всё гуд, но надо тоже самое для  документов. Документы самое узкое место.
  
Наверх
ICQ  
IP записан
 
an2
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 43
Зарегистрирован: 23. Марта 2012
Re: Справочник плюс. Прямая запись и чтение в справочники 1С 7.7
Ответ #11 - 31. Мая 2012 :: 14:41
Печать  
Я не попрошайка, но попрошайничать умею Улыбка
Если все гуд можно + на инфостарт?

За документы в длижайшее время собираюсь взяться.
Пока мое мнение такое:
Городить такой огород с документами нет смысла.
По двум причинам:
1 Броться нужно всего с одной хранимой процедурой, лочащей журнал.
2 Документам не нужна пореквизитная запись.

Пока я собираюсь для документов делать следующее
1. Научиться отключать верификацию.
2. Каждый раз после реструктуризации МД мениять хранимую процедуру, которая лочит журнал.
3. Намалевать класс-оболочку, который будет в полном объеме юзать 1с-овский функционал записи и проведения, единственное, что добавить, - функционал для блокировки интересующих ресурсов (записи в таблицах документов, остатки и движения регистров).

Из всего этого пока еще ничего даже не смортел Улыбка
  
Наверх
 
IP записан
 
aou1c
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 183
Местоположение: Екатеринбург
Зарегистрирован: 29. Мая 2006
Пол: Мужской
Re: Справочник плюс. Прямая запись и чтение в справочники 1С 7.7
Ответ #12 - 31. Мая 2012 :: 15:31
Печать  
Плюсанул.
по пункту 1 - есть скрипт, в т.ч. на этом форуме видал.
по 2 можно сделать как в МОД, там сравниваются атрибуты файла 1cv7.dd
по 3. Вот это интересно, то же делал давно, с заменой блокировок 1с,  но, вылеты 1с только участились, так и не победил
  
Наверх
ICQ  
IP записан
 
aou1c
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 183
Местоположение: Екатеринбург
Зарегистрирован: 29. Мая 2006
Пол: Мужской
Re: Справочник плюс. Прямая запись и чтение в справочники 1С 7.7
Ответ #13 - 31. Мая 2012 :: 15:35
Печать  
1 Броться нужно всего с одной хранимой процедурой, лочащей журнал.

Не согласен, еще нужно убирать блокировки с регистров. Это чтобы параллельно проводить документы одного вида, т.е. читай "гибкие блокировки"
  
Наверх
ICQ  
IP записан
 
an2
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 43
Зарегистрирован: 23. Марта 2012
Re: Справочник плюс. Прямая запись и чтение в справочники 1С 7.7
Ответ #14 - 31. Мая 2012 :: 15:41
Печать  
Я сторону блокировок документов еще не смотрел.
Думал что только Журнал документов и все.
А это не так??? Ужас
1с все остальное тоже лочит? Я честно говоря озадачен.
Если лочит все, тогда все намного сложнее чем я думал.
Иду курить DDS.
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 3 4
ОтправитьПечать