Имя: Пароль:
1C
1С v8
Вынести тяжелый запрос из транзакции записи
0 sbabay
 
07.11.12
16:07
Есть документ, который делает запись в регистр сведений, но перед записью в регистр, он собирает данные запросом из этого же регистра. Запрос тяжелый, поэтому иногда возникают блокировки, т.к. он выполняется в ОбработкеПроведения,  т.е. в транзакции. А значит при выполнении этого запроса блокируется весь РС и в него в этот момент уже никто ничего записать не может.
Подкиньте идею как это можно избежать. Как вытащить этот запрос "извне" транзакции записи (модуль формы не предлагать)?
1 France
 
07.11.12
16:10
упростить запрос тоже не предлагать??
кстати, регистр записи не блокируется... блокируются записи, попавшие в отбор по регистру.
2 shamannk
 
07.11.12
16:11
(0) Проверка перед проведением?
3 Maxus43
 
07.11.12
16:12
>>А значит при выполнении этого запроса блокируется весь РС и в него в этот момент уже никто ничего записать не может.
давно ли так?
4 Feanorko
 
07.11.12
16:13
Если блокировки возникают, значит это кому-нибудь нужно...)))
5 Maxus43
 
07.11.12
16:15
ДЛЯ ИЗМЕНЕНИЯ юзай, чтоб провести таки смог, пусть сотальные подождут
6 sbabay
 
07.11.12
16:16
(1) Упростить - это конечно первое, что надо сделать. Но пока это невозможно.

>> кстати, регистр записи не блокируется... блокируются записи, попавшие в отбор по регистру.

Можно поподробнее?
У меня там одно измерение. Подчинен регистратору, Периодичность по позиции регистратора. Есть вот такие участки:

ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.МойРС КАК МойРС
   |                ПО ДругаяТабл.Оборудование = МойРС.Оборудование
   |                    И (МойРС.Регистратор.МоментВремени > &МоментВремени)
   |                    И (НАЧАЛОПЕРИОДА(МойРС.Период, ДЕНЬ) = НАЧАЛОПЕРИОДА(ДругаяТабл.Дата, ДЕНЬ))
7 sbabay
 
07.11.12
16:17
(2) не понял вопроса
8 Feanorko
 
07.11.12
16:17
(6) давай запрос полностью, шо ле
9 sbabay
 
07.11.12
16:18
(5) мне б наоборот, сделать так, чтоб запрос выполнял "грязное" чтение и не накладывал блокировку на таблицу
10 NcSteel
 
07.11.12
16:18
(6) За это МойРС.Регистратор.МоментВремени повесить на первом суку.
11 Maxus43
 
07.11.12
16:18
(9) обычный запрос и не накладывает блокировку
12 sbabay
 
07.11.12
16:18
(8) он тут не поместиться. И особо править его сейчас без тестов не могу. Там много нюансов, которые могу упустить
13 ERWINS
 
07.11.12
16:19
упправляемые блокировки вместо автоматических?
14 Feanorko
 
07.11.12
16:19
(12) да ладно, не ломайся :)
15 sbabay
 
07.11.12
16:19
(11) в транзакции - накладывает
16 Feanorko
 
07.11.12
16:19
(9) тогда убери из запроса "ДЛЯ ИЗМЕНЕНИЯ"
17 NcSteel
 
07.11.12
16:19
(13) Тут рано еще пушку доставать, можно ище и винтовкой разобраться.
18 Maxus43
 
07.11.12
16:20
база файловая поди ещё?
19 Feanorko
 
07.11.12
16:20
(15) давно ли? :)
20 Maxus43
 
07.11.12
16:20
(15) не верю (с)
21 sbabay
 
07.11.12
16:20
(10) а практический совет есть?
22 NcSteel
 
07.11.12
16:20
(0) Перепиши запрос на нормальный или организуй корректное хранение данных.
23 sbabay
 
07.11.12
16:20
(22) это понятно, но это не одной недели/месяца работы
24 sbabay
 
07.11.12
16:21
(19) да, давно. Можешь проверить
25 ERWINS
 
07.11.12
16:21
(21) если скл то переведи на управляемые блокировки и он ничего не будет блокировать
26 sbabay
 
07.11.12
16:21
27 NcSteel
 
07.11.12
16:21
(21) Судя по запросу он должен выполняться максимально долго. Надо его переписать. выносить из транзакции запросы к данным необходимые при записи оъекта не правильно.
28 sbabay
 
07.11.12
16:21
(25) СКЛ. Блокировки управляемые
29 Reset
 
07.11.12
16:22
(19) (20) Вы чего? Всегда в автоматическом режиме на читаемые данные наклыдвалась разделяемая блокировка
30 NcSteel
 
07.11.12
16:22
(23) Лучше поработать в этом направление чем ловить блох в свитере Мани.
31 sbabay
 
07.11.12
16:22
(27) Это не контроль остатков, оно там особо и не нужно
32 NcSteel
 
07.11.12
16:23
(31) если нужен при проведении, то выносить нельзя.
33 sbabay
 
07.11.12
16:24
(10) Саш, а конкретно
МойРС.Регистратор.МоментВремени

на что изменил бы?
Отдельное левое соединение с регистратором и на него условие?
34 Maxus43
 
07.11.12
16:25
(29) пошёл читать библию...
35 NcSteel
 
07.11.12
16:25
(33) У тебя и так не явное левое соединение. Лучше всего пакетником собрать нужные Ссылки с отбором по моменту времени, а потом отобрать рс.
36 NcSteel
 
07.11.12
16:26
(35) + Чем больше типов сидит в "Регистраторе" тем быстрее будет явное соединение. Но структуру регистра надо перерабатывать. Например добавить реквизит.
37 ERWINS
 
07.11.12
16:27
(28) в этом доке стоят управляемые?
38 sbabay
 
07.11.12
16:27
(35) Я не тупой и понимаю как оно там делается. но вот твои упреки без конкретики меня и насторожили.

>>Лучше всего пакетником собрать нужные Ссылки с отбором по моменту времени, а потом отобрать рс.

точно лучше не будет
39 sbabay
 
07.11.12
16:27
(37) да
40 ERWINS
 
07.11.12
16:29
тогда не должно блокироваться....
41 NcSteel
 
07.11.12
16:30
(38) Будет. Так как при не явном соеднинии тянутся все поля. А тебе только ссылки нужны.
42 NcSteel
 
07.11.12
16:32
(41) А на пакетник Скуль может более оптимальный план нарисовать. В твоем случае на каждую строку РС строится отдельный цикл перебора записей регистраторов - что далеко не оптимально
43 sbabay
 
07.11.12
16:33
(42) ОК, убедил. Здесь можно и явно задать соединение.
Регистраторов очень много, выносить их выборку в отдельную ВТ точно не буду
44 Feanorko
 
07.11.12
16:34
(29) правильно ли понимаю, что запрос в транзакции при управляемых блокировках отправляет курить до окончания транзакции все остальные запросы к этой таблице в других сессиях?
45 NcSteel
 
07.11.12
16:34
(43) Все ровно это мышиная возня. Переделай регистр ей богу ))) не мучай операторов.
46 sbabay
 
07.11.12
16:35
(44) да, до окончании запроса, а не транзакции
47 sbabay
 
07.11.12
16:35
(45) уже начал, но все рано сабж интересен
48 NcSteel
 
07.11.12
16:35
(44) Формирование блокировок при выполнении запроса что в упр , что в автомате - одинаковок (если не сказать заранее кодом)
49 sbabay
 
07.11.12
16:37
а что кодом можно изменить?
50 Reset
 
07.11.12
16:39
(44) В автоматическом режиме, а не в управляемом. И не обязательно всю таблицу (зависит от sql)
51 ERWINS
 
07.11.12
16:39
(48) запрос в упр блокировках вообще не должен ничего блокировать, делал на 8.1 тесты, не блокируются
52 Reset
 
07.11.12
16:40
(50) Но автор заявил, что у него управляемый режим, так что это не актуально.
53 Feanorko
 
07.11.12
16:40
(48) (50) (51) чета нихрена уже не понимаю :)
54 NcSteel
 
07.11.12
16:41
(49) Конкретно указать зерно блокировки.
55 sbabay
 
07.11.12
16:42
(54) я про блокировки, которые накладываются в момент выполнения запроса к таблицам из этого запроса
56 Feanorko
 
07.11.12
16:42
(55) скока по времени запрос выполняется?
57 Reset
 
07.11.12
16:43
(55) В момент выполнения запроса не накладываются блокировки в управляемом режиме
58 Reset
 
07.11.12
16:44
(51) +
59 alexhtn
 
07.11.12
16:44
Если запрос очень тяжелый и лень что-то переделывать, то можно попробовать создать для него недостающие индексы в sql.
60 sbabay
 
07.11.12
16:45
(57) а есть этому подтверждения?
61 sbabay
 
07.11.12
16:47
Вот цитата из 8.3:

Работа с СУБД. Управляемые блокировки.
Как стало
При работе с Microsoft SQL Server версии 2005 и выше, используется режим управления версиями строк, если конфигурация использует режим управляемых блокировок. Используется уровень изоляции транзакций READ_COMMITED_SNAPSHOT. При чтении данных вне транзакций используется согласованное чтение.    
Результат изменения
К уменьшению блокировок и взаимоблокировок при выполнении запросов, работающих в транзакции;
62 NcSteel
 
07.11.12
16:47
(57) Накладываются.
63 Feanorko
 
07.11.12
16:48
(57) а чем чревата разделяемая блокировка в момент выполнения запроса? не даст другим сессия установить разделяемую блокировку на те же данные пока выполняется запрос и возможен облом по таймауту?
64 Reset
 
07.11.12
16:54
(63) Разделяемая дает возможность установить разделяемую и прочитать, но не дает установить исключительную и изменить. Т.е. ее наложение гарантирует неизменность данных внутри транзакции
65 NcSteel
 
07.11.12
16:55
В общем в упр режиме если ничего не делать то будет:

1. Начало транзакции
2. Выпонление запроса (селект) - установка блокировки
3. Получение результата запроса - блокировка снята
4. Внесение данных в соседнем сеансе
5. Читаем результат селекта - грязное чтение
6. Конец транзакции

Автор, а оно такое надо. Смысл тогда запрос юзать если данные грязные.
66 NcSteel
 
07.11.12
16:57
(64) Соседний сеан не сможет изменить данные - что в общем нормально.
67 sbabay
 
07.11.12
16:57
(65) ну оно как бы по этому измерению другими пользователями точно изменяться не будет
68 NcSteel
 
07.11.12
16:59
(67) А тут уже как план запроса построится и не факт что не будет избыточности. Поэтому лучше всего подсказывать скулю.
69 NcSteel
 
07.11.12
17:00
(68) + Причем только на выполнение селекта. А вот в момент чтение результата соседние ползователи могут спокойно колбасить.
70 Feanorko
 
07.11.12
17:07
(64) тогда вообще не понятно, каким образом это мешает автору
71 sbabay
 
07.11.12
17:07
А никто не в курсе как именно происходит блокировка при Селекте в транзакции? Блокируется пока не выполнится весь пакет или блокировка ставится/снимается сразу после выполнения отдельного куска?
72 NcSteel
 
07.11.12
17:10
(71) Пока весь пакет не выполнится блокировка не снимется
73 sbabay
 
07.11.12
17:10
И еще попутно вопрос. ЦУП мне показал следующий блокирующий запрос:
SELECT TOP 20001
*
FROM _InfoRg3840 T1
WHERE T1._RecorderTRef = ? AND T1._RecorderRRef = ?
ORDER BY T1._LineNo

На строках кода:

ОбщийМодуль.ПроведениеСервер.Модуль : 77 : Объект.Движения.Записать();


Что это? откуда эта цифра 20001 ??
74 sbabay
 
07.11.12
17:12
(72) тогда можно будет попробовать разбить этот запрос на несколько. Ибо обращение к этому регистру идет далеко не везде.
А откуда инфа, если не секрет?
75 Feanorko
 
07.11.12
17:13
(73) а скока записей в наборе записей записывается?
76 sbabay
 
07.11.12
17:15
И еще из того же ЦУПа.
Блокирующий запрос:
DELETE FROM T1
FROM _InfoRg3840 T1
WHERE T1._RecorderTRef = ? AND T1._RecorderRRef = ?
На тех же строках: ОбщийМодуль.ПроведениеСервер.Модуль : 77 : Объект.Движения.Записать();

и аналогичный заблокированный запрос, но уже из другого документа.

Я ожидал, что при управляемом режиме они не должны друг другу мешать (потому как наложен фильтр на конкретные РАЗНЫЕ регистраторы)
77 Feanorko
 
07.11.12
17:16
(76) очень похоже на эскалацию блокировок, запрос твой не при делах похоже
78 sbabay
 
07.11.12
17:17
(75) В одном документе чаще всего - одна )
Но куча этих документов может создаваться в транзакции записи другого "вышестоящего" документа.
79 Feanorko
 
07.11.12
17:17
(78) тогда моя не понимать :(
80 sbabay
 
07.11.12
17:17
(77) это значит не хватает памяти серверу?
81 krbIso
 
07.11.12
17:18
глянь план выполнения запроса, может у тебя скнирование там
82 sbabay
 
07.11.12
17:19
Запрос переделывать буду. Но всё будет комплексно. А пока с этим хочется разобраться
83 Feanorko
 
07.11.12
17:21
(80) я не уверен, что это имеет место быть, но цифра 20001 подозрительна) память тут не при делах
84 sbabay
 
07.11.12
17:24
(83) мне тоже это подозрительно. странно как-то
85 Jaffar
 
07.11.12
17:58
(83) а не ВЫБРАТЬ ПЕРВЫЕ 20001?
86 sbabay
 
08.11.12
08:40
(85) не понял