|
|
|
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, АЛьФ, Vol71
| ☑ | ||
|---|---|---|---|---|
|
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) тогда только закрывай курсор
|
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |