gifts2017

Освобождение переменных в 1С

Опубликовал Роман Романов (romansun) в раздел Программирование - Теория программирования

Как практически на пустом месте получить ошибку блокировки по причине неверного использования переменной.

Думаю, многие из нас в буднях своих работы в качестве IT-бухгалтера за всеми этими дебетами, кредитами, ОСВ и прочими платёжками порой забывают, что 1С - это в первую очередь язык программирования и ничто сугубо техническое ему не чуждо :).

 

Вот так и я, увидев в один прекрасный день вот такую картинку

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


Через n-ное время причина была найдена, очищена от шелухи и минимизирована до очевидного примера. Достаточно написать вот такой простой код в модуле объекта справочника


перем Об;

Процедура
ПередЗаписью(Отказ)

   
Об = ЭтотОбъект;

КонецПроцедуры

чтобы, к примеру, при пометке и тут же распометке на удаление элемента справочника сразу возникала эта ошибка. Блокировка снимается секунд через 15-20.

 

Проблема решается освобождением переменной:


перем Об;

Процедура
ПередЗаписью(Отказ)

   
Об = ЭтотОбъект;

   .... 
    Об = неопределено;
КонецПроцедуры


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

- оригинальная ситуация - пост 22.

- вероятные причины проблемы - пост 78, 94, 99

Спасибо всем, кто участвовал в прениях.

 

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Михаил Ражиков (tango) 07.02.11 20:49
(0) 1С - это в первую очередь язык программирования
в мемориз

а чё за картинко-то? автар, ты ее сам-то разглядишь?

**
в каком месте втыкаешь
Проблема решается освобождением переменной:

Об = неопределено;
?

на самом деле сабж - в развитие темы блокировок.
разверни, пока что - тема не раскрыта
2. Сергей Ожерельев (Поручик) 07.02.11 22:13
Гюльчатай, открой личи.., тьфу, автор, картинку-то покажи нормально. Или словами опиши, что за ошибка.
3. Роман Романов (romansun) 07.02.11 23:39
Упс, прошу покорнейше простить :oops: Исправил картинку.

Об = неопределено; - например, в ПередЗаписью перед концом процедуры. Самый нормальный вариант. (Дописал в саму заметку)

Развитие темы? Ох. Я уже лет 8 ни на чем кроме 1С не кодил, могу слажать :). Может, более опытные товарищи напомнят, подскажут?

Ну, общая идея, думаю, примерно такая - выражение "Об = ЭтотОбъект;" определяет переменную указывающую на объект. При закрытии (при выходе из модуля объекта) объекта переменная еще некоторое время остаётся жить, тем самым блокируя объект (область памяти) - запись справочника.

Если переменную Об не делать глобальной, то она самостоятельно уничтожается при выходе из процедуры ПередЗаписью().
4. Антон (anton.fly7) 08.02.11 08:36
а зачем эта переменная Об вообще нужна?
5. Ийон Тихий (cool.vlad4) 08.02.11 10:14
Название темы, конечно, отжигает - Освобождение переменных в 1С...из адского плена наверное...вообще даже не знаю, что и сказать...то ли автор начал подозревать о блокировках, то ли просто решил додумывать читателям самим...
ЗЫ И потом непонятно зачем переменной передавать ЭтотОбъект? Точнее непонятно зачем Об объявлять в начале модуля, подозреваю что таким образом вы передаете ее куда-то...хм...
ЗЫ Передавайте ЭтотОбъект.Ссылка, затем там где надо ПолучитьОбъект(), Записать() ....
6. Артем Гусаров (Flashback1979SE) 08.02.11 11:34
"перем Об;

Процедура ПередЗаписью(Отказ)

Об = ЭтотОбъект;

КонецПроцедуры"

осталось только объект в параметр сеанса загнать и вообще зачетный баг будет))), вообще фигасдва найдешь потом)

PS: пример учит правильно объявлять и использовать переменные - как предостережение)
7. Роман Романов (romansun) 08.02.11 11:36
Поясняю, что было в оригинале - в ПередЗаписью вызывается некая глобальная проверочная процедура, возвращающая статус отказа. Поскольку для нового объекта ссылки еще нет, то приходится оперировать объектом. И именно в том проверочном модуле происходит куча-куча всяких проверок, где в каком-то месте потребовалось объявить глобальную переменную.

Приведенный пример, конечно, вырожденный.
8. Роман Романов (romansun) 08.02.11 11:37
(6)

дададададада, совершенно верно :)
9. Ийон Тихий (cool.vlad4) 08.02.11 11:42
(7) При чем здесь процедура, да еще и глобальная и объявление переменной...Я догадывался для чего это вы сделали, но теперь понял, что (6) прав - это не статья о блокировках, это просто глупый баг, передавать таким образом объекты...так никто не делает...
ЗЫ Советую тогда тему статьи поменять и развить ее в русло правильного и неправильного использования и передачи переменных
ЗЫ Можно всегда посмотреть как в типовых проверки огранизуют....
Из типовой ОбработкаТабличныхЧастей.ПриЗаписиПроверитьСтавкуНДС(ЭтотОбъект, Товары) нет там никаких переменных объявленных в модуле
10. Роман Романов (romansun) 08.02.11 14:20
(9) Подправил чуть название, согласен, что слово "блокировка" может путать.

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

Насчет так никто не делает и объекты таким образом не передаёт: вот же и пример, собственно - "ОбработкаТабличныхЧастей.ПриЗаписиПроверитьСтавкуНДС(ЭтотОбъект, Товары);"

Про типовые конфы речи не идет, в моё случае конфа нетиповая и в разное время в неё вписывались разные люди.

Если отдельно взятый программист никогда не допустит такой ошибки (могущей быть абсолютно неочевидной ввиду наслоений кода), то честь ему и хвала. Тут я только пожму ему руку :).
11. Ийон Тихий (cool.vlad4) 08.02.11 14:29
(10) Где вы видите Перем Об;
Об = ЭтотОбъект
в типовой?
Там передается в процедуру ЭтотОбъект, которая тут же отрабатывает и все, нет никакой после этого пресловутой блокировки
12. Ийон Тихий (cool.vlad4) 08.02.11 14:37
Но вы наверное сделали бы по другому

Перем ЭтоМойОбъект;



Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
ЭтоМойОбъект = ЭтотОбъект;

ОбработкаТабличныхЧастей.ПриЗаписиПроверитьСтавкуНДС(ЭтоМойОбъект , Товары);



КонецПроцедуры
:D
13. Роман Романов (romansun) 08.02.11 15:11
не совсем так :)

модуль объекта:

Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения) 

  ОбработкаТабличныхЧастей.ПриЗаписиПроверитьСтавкуНДС(ЭтотОбъект , Товары); 

КонецПроцедуры
...Показать Скрыть


--------------------------------------------------------

модуль ОбработкаТабличныхЧастей:

Перем ЭтоМойОбъект;

Процедура ПриЗаписиПроверитьСтавкуНДС(ДокументОбъект , ТабличнаяЧасть)

  ЭтоМойОбъект = ДокументОбъект;

КонецПроцедуры
...Показать Скрыть


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

ЗЫ. Общий модуль тут плохой пример, поскольку там нельзя объявить переменную. Но в модуле обработки, к примеру, сделать это нам ничего не мешает.
14. Ийон Тихий (cool.vlad4) 08.02.11 15:47
(13) Не совсем так или совсем не так, в (12) был сарказм....
Смысл в чем --- Если вы делаете что-то в объекте например - Справочник.Номенклатура - то нафига там объявлять переменную, если ЭтотОбъект грубо говоря виден там отовсюду, если вы передаете в процедуры за пределы справочника в общие модули например, то можно передавать ЭтотОбъект, а теперь вопрос - нафига делать Об = ЭтотОбъект;? Возможно имеет в каких-то случаях смысл передавать ссылку, когда объект есть - ЭтотОбъект.Ссылка(в конце концов реквизит тоже может быть ссылочным), тогда можно там где необходимо изменять объект. Но я не могу придумать случай, когда переменной надо присваивать ЭтотОбъект. Ведь никакого присвоения нет, он просто указывает участок памяти на этотобъект и создает ссылку на переменную, так, что в конечном счете это тотже ЭтотОбъект. Потому и блокировка происходит. Объявленная переменная сразу не уничтожается (по всей видимости только после того как сработает сборщик мусора), а режим блокировки, никто не отменял, ведь ЭтотОбъект все еще висит. Смысл Об = ЭтотОбъект?
15. Ийон Тихий (cool.vlad4) 08.02.11 16:21
Да, возможны случаи, при рекурсивном вызове, когда проще сделать Об = ЭтотОбъект, но мне кажется лучше такой код переписать, хотя, конечно, можно сделать Об = ""
16. Роман Романов (romansun) 08.02.11 16:53
cool.vlad4 пишет:
Объявленная переменная сразу не уничтожается (по всей видимости только после того как сработает сборщик мусора), а режим блокировки, никто не отменял, ведь ЭтотОбъект все еще висит. Смысл Об = ЭтотОбъект?


Да, всё так и есть :). Именно об этом я и писал, что дескать, если кто-то когда-то напишет где-то вот такой по смыслу код - то увидит такую ошибку, а если увидит такую ошибку - то проверьте, возможно что причина кроется в таком коде.

Мне сложно сейчас судить именно для чего такое присвоение. Как пример, человеку нужно написать еще несколько процедур в стороннем чужом модуле, он видит что в первой процедуре есть подходящая входящая переменная и думает - а давай я сделаю себе с неё глобальную копию, чтоб и в других моих процедурах в этом модуле её было видно. При этом он не задумывается, а что именно это за переменная, какие происходят процессы и какие могут быть последствия.

Далее пишет свои процедуры, всё работает, все довольны. Но иногда выскакивают труднообъяснимые ошибки блокировки...


В моём конкретном случае, действительно, переменная "Об = ЭтотОбъект;" и всё что с ней связано оказалось реально лишним и было мной просто стёрто.
17. Михаил Ражиков (tango) 08.02.11 20:33
(16) ок, теперь в (0) указать, что тема раскрыта в каментах, и плюсики будут заслуженными
18. Аркадий Кучер (Abadonna) 08.02.11 21:26
Кхм... "Очищенный от шелухи" пример становится совсем непонятным
(1)
перем Об;

Процедура ПередЗаписью(Отказ)

    Об = ЭтотОбъект;
   .... 
    Об = неопределено;
КонецПроцедуры
...Показать Скрыть

Как написано тут переменная выходит за границы процедуры только как "неопределено"
Поэтому код выше абсолютно равносилен
(2)
Процедура ПередЗаписью(Отказ)

  //  Об = ЭтотОбъект;
   .... 
    Об = неопределено;
КонецПроцедуры
...Показать Скрыть

ибо в других процедурах мы достучимся только до Об = неопределено, а на фиг оно нам такое надо?
А в сухом остатке, он вообще равносилен
(3)
//перем Об;

Процедура ПередЗаписью(Отказ)

    //Об = ЭтотОбъект;
   .... 
    //Об = неопределено;
КонецПроцедуры
...Показать Скрыть
19. Роман Романов (romansun) 08.02.11 21:43
(18)

Хм... Таки да, нестыковка..

А если вариант описанный в (13), и из процедуры "ПриЗаписиПроверитьСтавкуНДС" вызывать еще ряд процедур (в них, в свою очередь, еще можно вызвать какие-то процедуры). И только в самой последней говорить "Об = неопределено" или в самой же процедуре "ПриЗаписиПроверитьСтавкуНДС" перед концом процедуры?

Даже и не знаю, какой пример сделать, чтобы он был и небольшим и понятным.

Мне кажется, варианты возможны всякие, даже самые бредовые, когда базу пишут поколения программистов, которые не сильно разбирают, что там дописано до них, а принимают всё это как абсолютно верно работающий черный ящик.
20. Ийон Тихий (cool.vlad4) 08.02.11 21:51
(18) Ну елы палы я ему битый час об этом далдычил -
Точнее непонятно зачем Об объявлять в начале модуля
и т.д. в камментах
21. Аркадий Кучер (Abadonna) 08.02.11 21:51
Я б на твоем месте просто написал:
- Ребята! Не запоминайте в глобальной переменной модуля объекта сам объект, если вам вдруг придет в голову такая бредовая идея! Чревато!
:D
Rain88; Scag; +2 Ответить 1
22. Роман Романов (romansun) 08.02.11 22:55
(20)(21)
:) я сегодня подождите..

Да, пример с кодом только в самом модуле объекта фиговый, вызывает больше недоумения.

Abadonna пишет:
Ребята! Не запоминайте в глобальной переменной модуля объекта сам объект, если вам вдруг придет в голову такая бредовая идея! Чревато!


Дык в том-то и дело, что последний человек редактировавший код залез в сторонний модуль. Встретил какую-то там нужную ему переменную в какой-то нужной ему процедуре, для подстраховки скопировал её, объявил глобальной и заюзал в своих процедурах (это как мне сейчас видится ситуация). И всё. А на то, что с переменной, которую он скопировал, передался через n процедур сам объект - внимания не обратил. Новый код исправно работал, в ошибки не падал. Прошло время... :)
И пользователи нет-нет, да и стали обращать внимание, что иногда на разных справочниках появляется ошибка блокировки, причем там где по идее её быть не должно.

Вот, в общем, и всё история. Дальше дело поручили мне и я долго и нудно пытался выяснить, при каких действиях происходит ошибка, кто виноват и что делать. В итоге оказался вот такой баг, да.
23. Аркадий Кучер (Abadonna) 08.02.11 23:00
(22) Что нашел - молодец, баг-то не особо очевидный. IMHO надо именно (22) и выложить в качестве текста статьи, а не
Об = неопределено;
24. Роман Романов (romansun) 08.02.11 23:05
Уфф, оказалось, что надо было сразу сказать всю правду, а не мутить воду вымыслами :)

Ок, спасибо, подумаю, как можно переписать текст статьи.

ЗЫ. Баг был и правду не очевиден - пользователи присылали скрины и говорили "вот, собственно... как так вышло, мы не знает, само как-то".
25. Аркадий Кучер (Abadonna) 08.02.11 23:23
Все вышеизложенное подтверждает мои подозрения, что разработчики 1С как не умели толком чистить за собой память в 7.7, так и 8.х до сих пор не научились :(
26. Роман Романов (romansun) 08.02.11 23:43
(25)
Ну, 1С сама в некотором роде "стимулирует" такое развитие. Ведь для написания простейшего учета пивного ларька даже и код писать не надо, всё на конструкторах - код, запросы. Многое 1С "додумывает" сама.

Плюс отсутствие серьёзной документации именно внутреннего технического характера. В основном только прикладная тематика.

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

Зато массовость и низкий порог вхождения в специальность... Мда..
27. Аркадий Кучер (Abadonna) 08.02.11 23:46
(26)Под
разработчики 1С
я и имел в виду разработчиков самой 1С.
Потому как
по всей видимости только после того как сработает сборщик мусора
- это ж фигня!
А если он через полдня сработает?
28. Аркадий Кучер (Abadonna) 09.02.11 00:08
Если уж совсем по честному, то тот чувак, который додумался объект в самом себе сделать глобальным, ничего особо криминального и не совершил.
Наверняка был уверен (и вполне обоснованно), что после использования объекта (то же интерактивное удаление) его деструктор (как во взрослых языках) сам за собой всё должен сразу же почистить.
29. Артур Аюханов (artbear) 09.02.11 10:19
(28) Если сборка мусора основана на подсчете ссылок на объект, как сделано в 77 (точно) и 8(подозреваю), то хранение в объекте ссылки на него самого как раз и приводит к багам к памятью.
Мы при разработке классов 1С++ на это много раз нарывались :(
30. Ийон Тихий (cool.vlad4) 09.02.11 10:43
(29) Я подозреваю, что так оно и есть.
А как иначе они (1С) могли сделать. Конечно, они могли сделать, что-то такое мощное как C#, где таких проблем быть не может, но думается мне позиция 1С была сделать простой и доступный интерпретируемый язык, которым сможет пользоватся даже оператор и бухгалтер, которые вряд ли бы осилили кодинг в C#, зато там со сборкой мусора проблем таких нет. строго говоря и глобально объявляемых переменных нет. Да и типизация там строгая...В общем цель 1С была сделать простой и доступный процедурный язык, если бы они еще сделали нормальный сбощик мусора, мне кажется простого языка бы не получилось. Вывод - тупо не использовать такие дырявые конструкции, которые тем более, что ни к чему.
ЗЫ Текучка памяти у 1С постоянно. И это не значит, что 1С кривой, а то, что код где-то не совсем корректный. А поскольку за черными ящиками не всегда догадываешься, что происходит, то проблему можно искать очень долго.
31. Андрей (AndrewEv) 09.02.11 11:48
я всегда об'являю переменные в НеОпределено
catNom = UnDefined;
Не сложно и проблем никогда не было
32. Роман Романов (romansun) 09.02.11 13:49
(31)
хороший пример самоорганизации, да :)
33. Аркадий Кучер (Abadonna) 09.02.11 14:00
(31), (32) Лично у меня нет никакой уверенности, что принудительное присвоение переменной значения = неопределено не может вызвать таких же глюков, как и изложенных с сабже. "Не то он украл, не то у него крали...." Где один глюк, там с таким же успехом может быть и другой.
В той же Дельфи иногда происходит глюк при неправильном использовании free, когда она своим деструктором пытается освободить память, которую программист уже освободил
34. Ийон Тихий (cool.vlad4) 09.02.11 14:57
Соглашусь с (33) - из крайности в крайность. Потом появится статья о странных переменных, которые вдруг становятся неопределенными. Делать надо как все, в хорошем смысле этого слова.
35. Алексей (alexqc) 10.02.11 11:05
(33) Почему? как раз все нормально. Механизм на подсчете ссылок, как artbear сказал. При присвоении Об=ЭтотОбъект увеличиваем счетчик у объекта, при "сбросе" (Об=ЧтоТоЕще) - уменьшаем. когда счетчик=0 - убиваем. И никаких глюков тут быть не должно.

И по поводу начального глюка - тоже ничего удивительного, оставили "висячую ссылку". Другой вариант например такой:

А=новый Массив;А.Добавить(А);

Либо так:
А=новый Массив;
Б=Новый Массив;
Б.добавить(А);
А.Добавить(Б);

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

На самом деле меня удивляет как раз то, что блокировка в конце-концов снимается. А это значит - что либо некий мусорщик все же есть, либо блокировка сама по таймауту сбрасывается, а объект остается.
36. Аркадий Кучер (Abadonna) 10.02.11 11:18
(35)
И по поводу начального глюка - тоже ничего удивительного, оставили "висячую ссылку".

А мне как раз удивительно. Раз уж 1С позиционируется как (щас камнями закидают! :D ) язык для домохозяек, то разработчики были просто обязаны были предусмотреть защиту от дурака.
Одно дело, когда я самолично (на свой страх и риск так сказать) даю команду GetMem(Массив, Размер), тогда я и должен сам позаботиться потом о
FreeMem(Массив, Размер). А если я его задал как var b: array[0..1023] of char дальше уже не мое дело как среда будет его потом подчищать.
При присвоении Об=ЭтотОбъект увеличиваем счетчик у объекта, при "сбросе" (Об=ЧтоТоЕще) - уменьшаем

Это мы думаем, что так должно быть, а как оно на самом деле - хз :(
37. Ийон Тихий (cool.vlad4) 10.02.11 12:25
(36) Абсолютно точно, что там происходит непонятно, или у кого-то исходники 1С появились? А писать то, что не всегда надо (Об = "" не всегда надо) считаю моветоном...да иногда это просто необходимо (например com), а насчет (35) сомневаюсь, что все там так просто (таймауты блокировок?), откройте объект(документ например) на целый день и он будет заблокирован на целый день, где тут таймаут. Сборщик видит, что на переменную нет ссылок и грубо говоря удаляет ее и все, затем просто перезаписываются участки памяти...
38. Ийон Тихий (cool.vlad4) 10.02.11 12:31
В конце концов процедуру можно написать Деструкция(Объект) --> Объект = "";
PS скоро умельцы напишут сборщик мусора на 1С :D
39. Ийон Тихий (cool.vlad4) 10.02.11 12:38
(35) Только сейчас заметил
что либо некий мусорщик все же есть
дык, конечно, есть...а иначе как? n-ное количество запросов бы иначе повесили систему моментально...
40. Алексей (alexqc) 10.02.11 12:51
(36) А оно и очищает. время жизни локально переменной - до конца функции, вышли - умерла. Поэтому пишем А=новый Массив(), и спокойно ждем когда среда его очистит.

В данном же случае другое. Это не локальная переменная, а переменной модуля - и она живет пока живет модуль. Модуль, очевидно живет пока живет объект. объект живет пока на него есть ссылки - из переменной ли, из внутренности системы (например, из открытой формы). И если ты присвоишь переменной _модуля объекта_ сам же объект - получим циклическую ссылку, -> на каждого из участников ссылка есть -> никто не умирает.

Это все равно что в яве написать нечто типа this.a=this. Но в яве подобный прикол специально разруливается мусорщиком (хотя всегда можно найти вариант, который GC не сможет обработать, либо для его обработки алгоритм сборки мусора будет медленным/затратным).
В 77 это решалось тем, что Контекст у формы не был ссылкой на непосредственно объект, а лишь содержал в себе эту ссылку. А при закрытии формы контекст по-любому чистился (в т.ч. и с этой ссылкой) - и было совершенно не важно, что еще ссылается на него.

В классах 1С++ контекст класса был ссылкой на объект, но специально контролировалось присваивание его члену.

В 8ке же подобная особенность просто отражена в документации. Не помню где, но я встречал как раз таки примеры и на счет ЭтотОбъект, и про двухсвязный список. Кроме того, утечки памяти можно поотслеживать при отладке в специальном режиме.

И на счет "язык для домохозяек" - именно 1С именно 8ку так не позиционирует, 8кой они замахиваются на "сурьезные" ERP-системы.
Собственно, у франчей 8рочники обычно "стОят" дороже 7рочников

А домохозяйкам по-идее должно хватить конструкторов :), и код руками типо писать не нужно.
41. Ийон Тихий (cool.vlad4) 10.02.11 12:53
(40) Пожалуй, да
ЗЫ пытаюсь проделать фокус автора, нифига не получается....разные пользователи и никаких проблем...
42. Аркадий Кучер (Abadonna) 10.02.11 12:54
Собственно, у франчей 8рочники обычно "стОят" дороже 7рочников

У нас одинаково. ;)
Абадона-77 получает столько же, сколько Абадонна-8х :D
43. Ийон Тихий (cool.vlad4) 10.02.11 12:59
Нифига не получается сделать тоже самое....
44. Ийон Тихий (cool.vlad4) 10.02.11 13:07
перем Об;

Процедура ПередЗаписью(Отказ)

Об = ЭтотОбъект;

....
Об = неопределено;
КонецПроцедуры

Подозреваю, что дело связано еще с .... из этого кода - поскольку попытки воспроизвести на скульной базе, на файловой, с одного компьютера, с нескольких, с одним пользователем, с несколькими, в модуле формы, модуле, у меня провалились. Никаких блокировок.
45. Ийон Тихий (cool.vlad4) 10.02.11 13:17
(0) Автор признавайся...ты хоть сам пробовал те куски кода, которые в статье...Нет никакой блокировки...либо приводи реальный код, где есть реальная блокировка...терзают смутные сомнения, что там еще более кривой код из-за которого вся петрушка...
46. Алексей (alexqc) 10.02.11 13:30
(37) Да, конечно _точно_ знать что там происходит можно только имея исходник, но по имеющимся данным, поведению системы и здравому смыслу можно предположить с _очень высокой вероятностью_. Ну ладно, это все лирика.

Я не проверял код автора, я ему поверил :). Автор пишет что блокировка снимается. Возможно, блокировка снимается по таймауту если объект никто не дергал, а открытая форма периодически стучит в рельсу "эй, я тут, открыт". Вот например что будет если присвоить переменной допустим допустим модуля какогото отчета объект (например элемент справочника), сделать ему Записать() и не закрывать этот отчет. Сколько провисит блокировка?

(39) Не понял, раскройте мысль плиз.

(42) А Абадона-ХХ франч или фри? Я почему-то считал что фри... Кстати, если вы таки работник франча, то уж наверно не тот кого там много и чей час стандартно в прайсе прописан, а наверно спец который итак дороже стоит?
47. Алексей (alexqc) 10.02.11 13:33
(41) (44) А что именно вы проверяете? Если с "Об = неопределено" (как в 44 написали)- то ничего и не будет, мыж все за собой почистили... или вы в 44 нето привели?
48. Ийон Тихий (cool.vlad4) 10.02.11 13:56
(47) Что я по вашему читать не умею? я в (44) скопипастил из статьи, естессно не то...вы сами то хоть проверяли?
49. Ийон Тихий (cool.vlad4) 10.02.11 13:58
(46) что непонятного в (39)? То что мусорщик какой-то есть? Уж что, что - а уж это то из здравого смысла...
50. Алексей (alexqc) 10.02.11 13:59
Проверил сам (правда не на справочнике, на документе, но думаю это не важно) - не срабатывает. И даже при явном указании Блокировка() - тоже не срабатывает. 1С:Предприятие 8.1 (8.1.15.14), режим блокировки - автоматический. Похоже, автор действительно чтото недоговариваеь.
51. Аркадий Кучер (Abadonna) 10.02.11 14:18
А Абадона-ХХ франч или фри? Я почему-то считал что фри

Абадонна с любыми префиксами - сотрудник аутсорсинговой компании, имеющей кроме прочего права франча.
Сервис-М

А вот сюда всех приглашаю на огонек ;)
1С: пользователям и программистам
52. Аркадий Кучер (Abadonna) 10.02.11 14:23
Нет никакой блокировки..

Есть! Лично проверил на справочнике Номенклатура. После "пометить на удаление" интерактивно в форме списка, "распометка" следом выдает "фигвам, блокировка". Правда не стал дожидаться потом разблокирует или нет? Щас тоже проверю
Прикрепленные файлы:
53. Аркадий Кучер (Abadonna) 10.02.11 14:36
+(52)
Модуль объекта:

Перем Об;

Процедура ПередЗаписью(Отказ)

Если ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
//.....................................

Об=ЭтотОбъект;
КонецПроцедуры // ПередЗаписью()
И нифига не снялась самостоятельно. Висит с момента предыдущего поста
54. Ийон Тихий (cool.vlad4) 10.02.11 14:39
(53) Что я, что Alexqc - делали в документе, выходит есть разница...
55. Алексей (alexqc) 10.02.11 14:40
(48) Ну мало-ли, всяко бывает. Точно так же как в пост, с налету код вставили в модуль, и "замыленым" глазом не заметили что там лишняя строчка в конце стоит.

(49) Не понятно при чем тут "много запросов" и GC?
Кстати, и вообще запросы к кому? К серверу, к базе, запросы памяти (тоже вариант, раз уж мы про GC говорим).
Если имеются в виду запросы к базе - то это все выполняется внутри, и пользовательский код ими не управляет. И как они сделаны мы знать не можем - а там совсем не обязательно объекты в куче, это может быть например простая очередь.

Ели об объектах языка "Запрос" - то тут все то же самое - объект живет пока на него есть ссылки, т.е. вот переменные ушли погулять, количество ссылок стало =0 - и Запрос автоматически умер. Специально выделенной сборки мусора тут не требуется. И значит ничего явно не говорит о том что тут есть GC.

На всякий случай (вдруг мы о разном говорим) - во всем контексте нашего обсуждения под "сборкой мусора" я понимаю _отдельный_ механизм, (периодически) проверяющий память на предмет нахождения и уничтожения ненужных объектов. Подсчет количества ссылок с самоуничтожением объектов я сюда не отношу.
56. Ийон Тихий (cool.vlad4) 10.02.11 14:42
(55) Да я не про 1С-ные запросы... а к памяти...Подсчет количества ссылок с самоуничтожением объектов - я же отношу. Вот поэтому у нас нестыковка...Если не относить - тогда, да, я соглашусь.
57. Ийон Тихий (cool.vlad4) 10.02.11 14:49
педивикия не аргумент, но тем не менее - (55) http://en.wikipedia.org/wiki/Reference_counting

In computer science, reference counting is a technique of storing the number of references, pointers, or handles to a resource such as an object, block of memory, disk space or other resource. It may also refer, more specifically, to a garbage collection algorithm that uses these reference counts to deallocate objects which are no longer referenced.
58. Аркадий Кучер (Abadonna) 10.02.11 15:13
Кстати, я понял откуда взялось так называемое "потом саморазблокируется".
Ничего оно не саморазблокируется, просто если потом поработать с другим элементом справочника, тем же кодом (Об=ЭтотОбъект) блокирнется уже он, а прежний "отпустит"
cool.vlad4; +1 Ответить 1
59. Ийон Тихий (cool.vlad4) 10.02.11 15:15
(58) Я сразу начал чего-то подозревать, что дело нечисто...Но у меня нивкакую не получается ни со справочником ни с чем воспроизвести....
60. Аркадий Кучер (Abadonna) 10.02.11 15:24
(59)
Но у меня нивкакую не получается

Движок 8.2 (8.2.13.202)
Та же фигня. А ты, сорри,в каком модуле код вставляешь?
Надо именно в модуле всего объекта: Действия - Открыть модуль объекта в Конфигураторе
А по поводу
блокирнется уже он, а прежний "отпустит"
это я соврал :( В смысле я тут начал эсперементировать когда Об воообще глобальная Экспорт.
В эксперименте с 8.2 оба элемента благополучно блокирнулись
61. Ийон Тихий (cool.vlad4) 10.02.11 15:25
(60) Именно в этом...получилось при распометке - пометке удаления, в консоли сервера можно посмотреть висячие блокировки - призаписи видать блокировки не возникает - потому как передзаписью вызывается опять Об = ЭтотОбъект. В общем сабж в "кровосмешении" блокировок и кривого кода.
PS Про запись и я соврал, то он блокирует, то нет.
62. Ийон Тихий (cool.vlad4) 10.02.11 15:30
:D Новое чудо техники 1С - запрет на любое редактирование -- консервирование объектов, называется прощай память....
63. Алексей (alexqc) 10.02.11 15:31
А почемму по английски, там и русская статья есть, практически такая же?

Короче, резюмируя: _сборка_ мусора - механизм, обеспечивающий удаление ненужных объектов; одним из вариантов реализации является _сборщик_ мусора - процесс, ищущий эти самые объекты. Автоподсчет ссылок с автоудалением - другой механизм, при этом сам _сборщик мусора_ ("мусорщик") отсутствует (или так - каждый объект сам себе мусорщик). Допускаю что теоретически м.б. вариант и с тем и с тем, но ИМХО он избыточен.

Фсе, завязываем с философией :)
64. Роман Романов (romansun) 10.02.11 15:31
ничо себе вы тут развернули!!

(45)
признаюсь :)
Abadonna получил верный скрин, да :)

(54) таки да, вроде не на всех доках блочилось. Попробую проверить и уточнить.

В целом - там возможны комбинации. Я игрался часа полтора с этим косяком: как можно поставить блок, как снять, возможна ли редакция при блоке, снимается ли блокировка редакцией и пр. и пр. В некоторых случаях блок снимался просто открывая форму, редактируя что-нить (получая модифицированность) и не записывая, закрывая. В других - даже не давало редактировать поля на форме, сразу ругалось.
65. Аркадий Кучер (Abadonna) 10.02.11 15:32
(63) А философия простая: лопухнулись разработчики, не предусмотрели такого дикого варианта, а надо бы...
66. Алексей (alexqc) 10.02.11 15:35
Слушайте, уже интересно. У меня на 81 ну никак не хочет блокироваться. может это только на 82?
67. Аркадий Кучер (Abadonna) 10.02.11 15:36
(66) Картинка (52) - 1С:Предприятие 8.1 (8.1.15.14)
Уточню - файловый вариант. Ибо я дома
68. Ийон Тихий (cool.vlad4) 10.02.11 15:37
(66) Не - у меня 81,...есть у меня подозрения...надо обдуматьь
69. Аркадий Кучер (Abadonna) 10.02.11 15:40
(66) Еще нюанс
Если у тебя просто Об=ЭтотОбъект - и не блокирнется никогда, ибо такой Об сразу чистится при выходе из процедуры
Надо, чтобы было именно вверху модуля
Перем Об;
70. Ийон Тихий (cool.vlad4) 10.02.11 15:45
Обязательно заблокируется , после изменения любого реквизита, к примеру пометки удаления, ан нет только пометки удаления...забавно...
71. Аркадий Кучер (Abadonna) 10.02.11 15:52
(70) Во, а мы тут слышим речи про "увеличили счетчик ссылок" :D
Подтверждаю - после изменения (например, наименования) и записи элемента ни фига не блокируется, хотя, по логике, вызывается та же ПередЗаписью() и так же должна увеличивать счетчик ссылок. Вывод: когда закрывается форма - она таки за собой все чистит, а вот если она и не вызывалась (пометка) - тогда ничего и не чистится.
Так что - косяк разработчиков, кто бы мне какие теории не выдвигал ;)
72. Ийон Тихий (cool.vlad4) 10.02.11 15:57
(71) Согласен полностью...уже дошло до меня...потому молчу..
73. Михаил Ражиков (tango) 10.02.11 16:09
74. Ийон Тихий (cool.vlad4) 10.02.11 16:11
(71) Плюс там еще другой косяк - при установке пометки удаления, она устанавливается до события передзаписью (в отладчике можно посмотреть) Именно поэтому она всегда срабатывает. Потому как объект еще заблокирован, после Об = ЭтотОбъект, он снова блокируется.
Первое, что приходит на ум для проверки
ПередЗаписью

Попытка
ЭтотОбъект.Разблокировать();
Исключение
Сообщить("ни фига");
КонецПопытки;


_______
и т.д.

Новое событие ПометкаПриИзменении() :D передпередзаписью()
75. Ийон Тихий (cool.vlad4) 10.02.11 16:24
Кто не верит код передзаписью() Если ПометкаУдаления Тогда ПометкаУдаления = Ложь; КонецЕсли; пометка будет всегда ложь.опечатался в первый раз
76. Роман Романов (romansun) 10.02.11 16:30
Попробовал внешней обработкой прямого изменения реквизитов - залоченный контрагент редактируется успешно. Интерактивно - фиг, сразу ошибка. Ни даётся ни один реквизит.
77. Ийон Тихий (cool.vlad4) 10.02.11 16:42
Не все таки 1С прогерам респект - они же не могли все предусмотреть...как например такой перл ПередЗаписью ЭтотОбъект.Записать() КонецПро... :D
ЗЫ Зато я теперь знаю как 1С того...сломить...
ЗЫ Скорее всего поэтому они пометку сделали до передзаписью - поскольку пометку надо делать без проверки, соответственно Записать() и тогда естессно до передзаписью. Т.е. при изменении пометки в списке, он записывает без событий передзаписью и т.д.
78. Ийон Тихий (cool.vlad4) 10.02.11 22:26
Эх все молчат...все таки не постесняюсь и озвучу свои подозрения в (68). Как мне кажется все достаточно тривиально. Сборщики не причем и свою работу они выполняют прекрасно. Я уже намекнул в (74) (Разблокировать()) в чем как мне кажется проблема. При оперировании формой включается свой атрибут контекста и ЭтотОбъект.Заблокирован() тупо затирается, почему этот трюк и не прокатывает (так по идее и должно быть) - срабатывает событие формы, оно и затирает значение заблокирован() (еще бы - пользователь открыл и закрыл, соответственно усе - это если один пользователь). Модуль же срабатывает в случаях когда форма не нужна/не причем - хитрая пометка удаления. Он при каждой записи проверяет ЭтотОбъект.Заблокирован() или нет. И соответственно решает, что делать. При пометке удаления срабатывает две записи (грубо говоря, событие то все равно одно) - первая изменяет значение пометки, второе это обработчик события ПередЗаписью в модуле. И вот здесь он присваивает переменной (фактически это ссылка, сначала думал указатель, возможно, но тогда почему не затирается другими данными) ЭтотОбъект со всеми потрохами, в том числе ЭтотОбъект.Заблокирован()(Истина в момент записи), после записи естессно удаляется переменная (ссылка) - иначе бы контекст на нее существовал, но менеджер записи (ЭтотОбъект) все еще висит. ЭтотОбъект.Заблокирован() все еще истина. К примеру я создал глобальную (для того чтобы в отладчике на нее поглядеть) переменную и вот. Но этот фокус срабатывает не только передзаписью еще и в самом модуле. Видать все по тем же причинам. Т.е. все это из-за хитрости ЭтотОбъект. Который оперирует в частности Заблокирован() в зависимости от контекста. Если пользователь первый открыл форму, то у него свой контекст, если другой пользователь, то у него естессно заблокировано.
Прикрепленные файлы:
79. Аркадий Кучер (Abadonna) 10.02.11 22:33
Эх все молчат..

Ясно дело ;) Я тут уже с BASS.DLL разбираюсь да графические эквалайзеры строю, а ты все про глюки 1С :D
80. Ийон Тихий (cool.vlad4) 10.02.11 22:35
(79) Вообще-то я уже почти 2 сайта распарсил :D ну и фильмец поглядываю...
81. Аркадий Кучер (Abadonna) 10.02.11 22:39
OFF: давно хотел плейер замутить с графикой по спектру (посмотрю, может в Miracle засуну)
82. Ийон Тихий (cool.vlad4) 10.02.11 22:40
(81) А эквалайзер будет?
офф то ли я сработы уставший, то ли два с половиной человека действительно смешной сериал
ЗЫ AIMP 1C Copyrigt Abadonna :D прикольно будет
83. Аркадий Кучер (Abadonna) 10.02.11 22:44
вот однако ;)
) А эквалайзер будет?

Да вот оно: BASS_SetEAXParameters
теперь только что обезьяна не приделает ;)
Прикрепленные файлы:
84. Сергей (Che) Коцюра (CheBurator) 10.02.11 23:10
Аркадий, занялись бы вы полезным делом.. ;-)
85. Аркадий Кучер (Abadonna) 10.02.11 23:21
Кому полезным? Да еще и в три ночи? :D
86. Роман Романов (romansun) 11.02.11 00:50
(78)
Сидел на работе и тыкал в Del. Работу забросил :(

Выяснил, что открытие формы заблоченного объекта и закрытие по "ОК" иногда снимает блок (просто "Записать" не снимает никогда). А иногда - не снимает, и в этом случае снять удаётся только перезапуском сеанса. На обработки прямой перезаписи реквизита блок не влияет вообще. Даже если перезаписывать "реквизит" "ПометкаУдаления" )) .

Если это в чем-то поможет теории из 78 поста - буду рад ))

Поднял оригинальную задачу из нашего багтрекера - у пользователей блочились-таки документы... Но сейчас у себя повторить не смог. Короче, дело ясное, что дело темное.

(85)
широка страна моя родная... а ведь потребовалось некоторое время, чтоб понять почему три ночи, када у меня половина двенадцатого (почему-то подумалось "холодно у них наверно..." :) )
87. Аркадий Кучер (Abadonna) 11.02.11 06:42
(86) Насчет холодно - не особо, минус 10 сейчас. Вообще-то мы точно на широте Москвы находимся.
А вот что вчера...землетрясение было, это да;)
Землетрясение
Лично я ни фига не почувствовал.
88. Александр Рытов (Арчибальд) 11.02.11 08:43
(87)
Лично я ни фига не почувствовал.
А не поучаствовал?
89. Аркадий Кучер (Abadonna) 11.02.11 08:46
90. Артур Аюханов (artbear) 11.02.11 15:43
Лично я уверен на 99,9%, что 1С использует именно подсчет ссылок, а спец.сборщик мусора - давно известные примеры с зацикливанием это только подтверждают.
Подсчет ссылок довольно удобен, если не ошибаться с циклическими ссылками, и просто в эксплуатации и разработке.
91. Аркадий Кучер (Abadonna) 11.02.11 15:46
(90) А (71) читал? Там куда ссылки подевались?
92. Ийон Тихий (cool.vlad4) 11.02.11 16:38
(90) Может это и так, да в общем никто этого и не отрицал, но здесь не тот случай. Проблема обмусолена - вывод - блокировка объекта из-за неправильного использования ЭтотОбъект. Решается проблема Об = Неопределенно(и то я уверен не во всех случаях) не из-за проблем, связанных со сборщиком, а из-за того что освобождается атрибут контекста ЭтотОбъект и объект разблокируется.
93. Аркадий Кучер (Abadonna) 12.02.11 07:51
off: + (83)
Дурачок любит красненький клочок ;)
Таки домутил я почти плейер. Теперь думаю - на фига? :D
Прикрепленные файлы:
94. USER--1C USER--1C (USER--1C) 12.02.11 11:00
В переменную записан объект в процедуре ПередЗаписью.
Читаем букварь: 1С:Предприятие 8.2 Практическое пособие разработчика,
стр. 442, 3 абзац:
"Если обращение происходит в пределах 20 секунд после поступления данных в кэш, данные считаются верными (валидными). Если превысил 20 секунд, будет выполняться проверка на соответствие версии данных, хранящихся в кэше, версии данных, находящихся в базе данных".

стр. 443, 3 абзац:
"При считывании данных в транзакционный кэш устанавливается блокировка на данные в базе данных, поэтому они гарантированно не могут быть изменены до окончания транзакции".

Т.е. пытается считать объект, заблокированный в транзакции, после 20 сек. "отпускает".
95. Аркадий Кучер (Abadonna) 12.02.11 11:18
(94)
В переменную записан объект в процедуре ПередЗаписью.

Блин, читайте (71)
после изменения (например, наименования) и записи элемента ни фига не блокируется, хотя, по логике, вызывается та же ПередЗаписью()

Изменяем наименование, записываем, точно так же
В переменную записан объект в процедуре ПередЗаписью.

НЕ БЛОКИРУЕТСЯ! Блокируется только в том случае, когда форма вообще не вызывалась, т.е. при установке пометки в списке.
Не так все тут однозначно, как мечталось бы...
96. Ийон Тихий (cool.vlad4) 12.02.11 11:53
(94)Офф Какие книжки ты еще знаешь?(риторический вопрос)
Ты хоть сам пробовал сделать, что описано в (0) - какие нафиг 20 секунд, полдня висеть будет, если не больше. Почитай, что было написано выше, может чего поймешь.
97. Михаил Ражиков (tango) 12.02.11 12:16
господа, пианист играет как может.
98. Аркадий Кучер (Abadonna) 12.02.11 13:28
господа, пианист играет как может.

Во-первых, в оригинале - "тапёр"
Во-вторых,никто в него и не стрелял ;)
99. Алексей (alexqc) 14.02.11 11:04
(98) Счас я с своим ворчливым характером выстрелю.

---
"Если обращение происходит в пределах 20 секунд после поступления данных в кэш, данные считаются верными (валидными)."
- Здесь речь идет о ЧТЕНИИ. Т.е. если у нас объект прожил более 20 сек - мы его еще раз перечитываем. К блокировке отношения ну никакого.

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

- Здесь речь о ТРАНЗАКЦИИ. Транзакционная блокировка (скорее всего, она и делается средствами сервера БД а не сервера 1С) умрет с окончанием/отменой транзакции, и никакие 20 сек тут ни при чем: транзакция может закончится быстро ( и блокировка снимется) или провисеть хоть час - тогда и блокировка час висеть будет.

Тапер, по ходу, ноты знает, да с ритма сбивается.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа