|
|
v7: Недопустимое состояние курсора
palsergeich, Гость из Мариуполя, Олдж, craxx, mikecool, 1snik_d, toypaul, trad, Наивный, zenik, maxab72, CaptanG, Chai Nic, Franchiser, Garikk, MWWRuza, leshikkam, Builder, Буковка, Voronve, nick86, Ёпрст, Иваныч1975, АгентБезопаснойНацио, Vstur, Мыш серый, СвинТуз, AlexKimp, skafandr, fbear, Dedal, p-soft, Волшебник, backfire, Ильф, Hawk_1c, Лодырь, Kongo2019, Fedor-1971, АЛьФ
| ☑ |
|
0
1snik_d
18.11.25
✎
15:13
|
Всем привет. Есть база 7.7 сильно переписанная ТиС, используются прямые запросы, FormEx и т.д., имеется УРБД. Суть проблемы следующая: есть прямой запрос, который вставляет в таблицу регистрации изменений УРБД записи для отправки справочников в нужные периферийки по условию. Периодически при попытке выполнения такого запроса вылетает критическая ошибка "Недопустимое состояние курсора" и 1С тупо закрывается. Перед этим обычно происходит deadlock. Помогите решить проблему, хотя бы с какой стороны подойти к решению.
|
|
|
1
arsik
гуру
18.11.25
✎
15:15
|
(0) Перед вставкой наверно нужно блокировку наложить. Не?
|
|
|
2
1snik_d
18.11.25
✎
15:24
|
ТекстЗапроса = "
|DECLARE @SelectedId char(9)
|DECLARE @SelectedDef int
|DECLARE @SelectedSign char(3)
|DECLARE @count int
|SET @SelectedId=?
|SET @SelectedDef=?
|SET @SelectedSign=?
|UPDATE _1sjourn SET verstamp=(SELECT verstamp FROM _1sjourn WHERE iddocdef=@SelectedDef AND iddoc=@SelectedId)+1
|WHERE iddocdef=@SelectedDef AND iddoc=@SelectedId
|SET @count=(SELECT count(*) FROM _1supdts WHERE typeid=@SelectedDef AND objid=@SelectedId AND dbsign=@SelectedSign)
|IF @Count=0
|BEGIN INSERT INTO _1supdts VALUES (@SelectedSign,@SelectedDef,@SelectedId,' ',' ')
|END
|ELSE
|BEGIN
|UPDATE _1supdts SET dwnldid='' WHERE Typeid=@SelectedDef AND Objid=@SelectedId AND DBSign=@SelectedSign
|END";
Если Элемент.Выбран() = 1 Тогда
ИдЭлемента = глMDW.ЗначениеВСтрокуБД(Элемент);
ДефЭлемента = глMDW.ИДСправочника(Элемент.Вид());
глRecordSet1CPP.ДобПараметр(1,14,9,0);
глRecordSet1CPP.ДобПараметр(1,4,4,0);
глRecordSet1CPP.ДобПараметр(1,14,3,0);
глRecordSet1CPP.УстПараметр(1, ИдЭлемента);
глRecordSet1CPP.УстПараметр(2, ДефЭлемента);
глRecordSet1CPP.УстПараметр(3, ИдБазы);
глRecordSet1CPP.ВыполнитьСкалярный(ТекстЗапроса);
глRecordSet1CPP.УдалитьПараметры(); // Удалить параметры
КонецЕсли;
Вот такой запрос выполняется для вставки.
|
|
|
3
1snik_d
18.11.25
✎
16:09
|
(1) А разве она сама не накладывается автоматически?
|
|
|
4
trad
18.11.25
✎
16:38
|
set nocount on
в начале запроса
|
|
|
5
1snik_d
18.11.25
✎
17:07
|
|UPDATE _1sjourn SET verstamp=(SELECT verstamp FROM _1sjourn WHERE iddocdef=@SelectedDef AND iddoc=@SelectedId)+1
|WHERE iddocdef=@SelectedDef AND iddoc=@SelectedId
Вот это я так понимаю тоже можно выкинуть, если регистрируются только справочники, без документов?
|
|
|
6
Ёпрст
гуру
18.11.25
✎
17:31
|
(5) да
|
|
|
7
1snik_d
18.11.25
✎
20:41
|
Спасибо за ответы, внес правки, буду наблюдать за поведением 1С.
|
|
|
8
АгентБезопасной Нацио
19.11.25
✎
13:56
|
(5) а зачем вообще verstamp трогать? ты ж не изменяешь док.
|
|
|
9
Лодырь
19.11.25
✎
14:22
|
(8) принудительная регистрация к обмену
|
|
|
10
АгентБезопасной Нацио
19.11.25
✎
15:43
|
(9) Принудительная регистрация - это как раз запись в updts.
изменять верстамп для этого совршенно не нужно. Верстамп нужен для разрешения коллизий.
|
|
|
11
1snik_d
19.11.25
✎
16:08
|
В общем добавление set nocount on в начало запроса не помогло. Все равно вылеты с этой ошибкой. Перед вылетом всегда deadlock. Если отключить эту регистрацию прямым запросом, то падения не происходит. Просто вылетает сообщение о deadlock и все.
|
|
|
12
1snik_d
19.11.25
✎
16:16
|
Есть подозрение, что в момент выполнения этого прямого запроса к таблице _1supdts, она параллельно изменяется УРБД и при попытке обновления найденной записи в таблице падает, т.к. записи уже нет, например
|
|
|
13
Franchiser
19.11.25
✎
16:16
|
SELECT verstamp FROM _1sjourn (nolock)
|
|
|
14
1snik_d
19.11.25
✎
16:17
|
(13) Я уже выкинул из запроса журнал документов, он мне не требуется
|
|
|
15
Franchiser
19.11.25
✎
16:33
|
Тогда так
FROM _1supdts (nolock).
Возможно ещё нужно объявлять курсор, и делать deallocate.
Добавь глRecordSet1CPP.Закрыть();
|
|
|
16
1snik_d
19.11.25
✎
16:31
|
(15) ЧТо-то я не уверен, что nolock правильный вариант, точность данных может нарушиться. Получается чтение того, что где-то в параллеллном сеансе можем апдейтнуться
|
|
|
17
Franchiser
19.11.25
✎
16:39
|
(16) тогда только закрывай курсор
|
|