1С взаимоблокировки при записи в регистр. #722929


#0 by ejikbeznojek
Добрый день. Имеется беда с которой борюсь уже 2ю неделю 8((( Есть самописная конфигурация 8.1 . База скулёвая. Есть Документ формирующий записи в регистр сведений. И есть 20 компьютеров с которых эти документы очень быстро создают. Могут раз в 20 секунд документ создавать с каждого компа. В документ сканируется товар в количестве 1-3000 коробок. И на каждую коробку создаётся запись в регистре сведений.(т.е. при проведении документа может создаваться 1-3000 записей в регистре) Соответственно у меня появилась беда со взаимоблокировками. Я пытался её решить несколькими путями: 1. Создал константу с типом булева. И перед записью в регистр сначала проверял, есть ли галка. Если есть то ждал 60 секунд или пока не снимется галка. Потом галку ставил, делал записи в регистр, галку снимал. 2. Где-то вычитал что блокируются все константы, и вместо констант сделал новый регистр из одной записи. И аналогично работал с ним. В итоге блокируется теперь новый регистр, я уже и различные попытки ставил и паузы. Теперь пишет в данной транзакции уже происходили ошибки. Код выглядит так:
#1 by Alex_MA
Совет: Запусти консоль кластера 1С. Пытайся добиться взаимоблокировки. Отслеживай блокировки по консоли - увидишь кто кого блокирует => узнаешь какой сеанс что запустил. Дальше анализируешь выполнение операций этими двумя сеансами. Если не получается проанализировать запускай профайлер mssql. Там событие Deadlock graph - сохрани в xml и разбирай. В этом xml будет описание: запрос_1 и запрос_2, а так же блокирующиеся ресурсы. Попытайся эту информацию сопоставить с кодом 1С и исправить ошибку. Удачи
#2 by Alex_MA
и сразу же настораживает: ПолучитьКонстантуБлокировкиИнформацииШКЛН УстановитьКонстантуБлокировкиИнформацииШКЛН
#3 by ejikbeznojek
Ну это функция и процедура, я их код чуть ниже написал
#4 by ejikbeznojek
Собственно на 99% я уверен что они и вызывают блокировку, но не пойму как этого избежать
#5 by ejikbeznojek
при выполнении "Выборка = Запрос.Выполнить.Выбрать;" ругается иногда, в данной транзакции уже происходили ошибки.
#6 by rsv
Переходите на 8.2  т.к. можно перейти в управляемый режим (понизить  до  read comm ) и перейти в режим разделения итогов.
#7 by ejikbeznojek
Я бы и рад)) Но мне сказали, что переход в ближайшие 2 года неосуществим))
#8 by Alex_MA
суть примерно скорее такова: 1сеанс выполняет блокировку Рес_1 2сеанс выполняет блокировку Рес_2 далее 1сеанс выполняет блокировку Рес_2 2сеанс выполняет блокировку Рес_1 захват ресурсов в разном порядке из разных транзакций - подумай над этим
#9 by ejikbeznojek
не совсем пойму. Регистр то у меня тут 1, и в нём всего одна запись. Я задумывал, что если взаимоблокировка происходит, то отрабатывает исключение, и так 10 попыток. Если за 10 раз все попытки не успешные, то всё равно возвращается истина.
#10 by КартузПива
Погоди. Одно дело УФ, второе - смена платформы. Работать сейчас на 8.1 в толстом клиенте - верх глупости. Все уже давно перешли на 8.2.
#11 by ejikbeznojek
Возможно)) Но у меня руководство убедить что нужен переход не получилось.
#12 by Зеленый пень
А вот и не все. Что за цирк с константой? Ответь сначала - откуда взаимоблокировки, регистр сведений подчинен регистратору или нет? Если нет - накладывай управляемые блокировки.
#13 by Necessitudo
Как вариант - прямые запросы.
#14 by ejikbeznojek
Ну я создал булеву константу. Перед записью проверяю истина ли она. Если ложь, то ставлю в константу истину и пишу в свой регистр и обратно ставлю в консту ложь. Если истина, то в цикле жду пока не станет ложь. Ну т.е. просто индикатор можно писать в регистр или нет. Я потом всё переделал аналогично, но вместо константы регистр сведений из 1й записи.
#15 by ejikbeznojek
Под прямыми запросами имеется ввиду "Select нужное поле From..."? А это точно избавит от взаимоблокировок?
#16 by Ник второй
Это и в 8.1 можно
#17 by Necessitudo
Конечно - особенно если сам наложишь тот уровень блокировки который захочешь.
#18 by ejikbeznojek
У меня режим управления блокировками в конфигураторе стоит "Автоматический". Насколько  понял нужно будет поставить "Автоматический и управляемый" это может негативно сказаться на старом коде?
#19 by Ник второй
1. Определить ресурс который блокируется, это можно быть вполне и не регистр и не константа. Определить можно например через ТЖ 2. Устранить проблему.
#20 by Ник второй
Вообще дурь.
#21 by Ник второй
нет
#22 by Ник второй
А какой смысл, если платформа позволяет штатно устанавливать различные уровни изоляции?
#23 by Necessitudo
В смысле дурь? Ты отменил BEGIN { TRAN | TRANSACTION } ?
#24 by Ник второй
Дурь в прямом смысле, так как "Платформа позволяет штатно устанавливать различные уровни изоляции"
#25 by Necessitudo
Платформа использует далеко не все уровни транзакции, которые предоставляет SQL сервер.
#26 by Ник второй
ну и какие в данном случае помогут, которые не использует платформа?
#27 by Necessitudo
Snapshot
#28 by Ник второй
И зачем тут он, если у нас только запись? 0_о
#29 by Necessitudo
Всего лишь запись, какие мелочи)))
#30 by Ник второй
+ и между прочем Snapshot 1С-ка штатно использует, но реально тут он ни к чему.
#31 by Necessitudo
Не ври, не использует.
#32 by Ник второй
Использует.... естественно не 8.1
#33 by Necessitudo
Я сказал Snapshot, а не Read Commited Snapshot.
#34 by Ник второй
Вот как раз Snapshot без Read Commited Snapshot может иметь больше проблем, так как позволяет устанавливать общую блокировку ресурса. Но если вернуться к задаче, то автору нужно грамотно изменить архитектуру регистров и возможно перевести на упр блокировки.
#35 by H A D G E H O G s
А можно спросить - нафига вообще этот огород?
#36 by Necessitudo
Письками помериться)
#37 by Ник второй
+100500
#38 by H A D G E H O G s
Чтобы пользователь сам каждый раз не жал повторно кнопку, а тупо смотрел в застывшую 1С или пошел пить кофе?
#39 by Ник второй
20 секунд это долго, и то можно поменять. А лучше всего изменить архитектуру, что бы блокировок в принципе не было.
#40 by MrStomak
Тебе объясняют, что в операциях записи в один ресурс две транзакции всегда несовместимы друг с другом, какой уровень изоляции ни поставь. В MSSQL проблема потерянного обновления решается даже в хинте WITH NOLOCK.
#41 by MM
А почему в запросе на чтение нет ДЛЯ ИЗМЕНЕНИЯ ? Для автоматического режима блокировок это обязательно.
#42 by Fragster
в имеено ВЗАИМОблокировки или таймауты?
#43 by Fragster
*именно
#44 by ejikbeznojek
Взаимоблокировки {Документ.ЛистНабора}: Ошибка при вызове метода контекста (Выполнить): Ошибка выполнения запроса "Конфликт блокировок при выполнении транзакции: Microsoft OLE DB Provider for SQL Server: Транзакция (идентификатор процесса 63) вызвала взаимоблокировку ресурсов блокировка с другим процессом и стала жертвой взаимоблокировки. Запустите транзакцию повторно.
#45 by MM
Конструкция ДЛЯ ИЗМЕНЕНИЯ в языке запросов, как раз и служит для борьбы с взаимоблокировками в автоматическом режиме.
#46 by Fragster
зачем там вообще чтение из РС?
#47 by hhhh
вот это полный бред: как можно было регистр назвать "Константы"? Вы - самоубийца.
#48 by hhhh
и потом например Результат имеет 99 строчек, вам надо взять последнюю, 99-ю, а вы берете самую первую строку: результат.Получить   ???????
Тэги: 1С 8
Ответить:
Комментарии доступны только авторизированным пользователям

В этой группе 1С