Имя: Пароль:
1C
1С v8
Конфиликты блокировок при проведении платежных документов
0 Alex_MA
 
22.05.14
11:42
Здравствуйте!

Клиент/Сервер MS SQL Server 2005 Standart
1С:Предприятие 8.2 (8.2.19.83)
УПП редакция 1.3 (1.3.51.5)

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

Документ имеет свойство "Движения"="Не удалять автоматически"

В результате в обработке проведения:

Процедура ОбработкаПроведения(Отказ, Режим)
    
    Перем Заголовок, СтруктураШапкиДокумента;
    
    Если мУдалятьДвижения Тогда
        ОбщегоНазначения.УдалитьДвиженияРегистратора(ЭтотОбъект, Отказ, Истина, Режим);
    КонецЕсли;

и далее происходит удаления движений по Хозрасчетному в процедуре:

Процедура ЗаписатьНаборЗаписейНаСервере(ИмяРегистра, Регистратор, ТаблицаДвижений = Неопределено, ТипРегистра = "РегистрНакопления") Экспорт
    
    Если ТипРегистра = "РегистрНакопления" Тогда
        Набор = РегистрыНакопления[ИмяРегистра].СоздатьНаборЗаписей();
        
        Если ТаблицаДвижений <> Неопределено Тогда
            Набор.мТаблицаДвижений = ТаблицаДвижений;
            ОбщегоНазначения.ВыполнитьДвижениеПоРегистру(Набор);        
        КонецЕсли;
        
    Иначе
        Если ТипРегистра = "РегистрБухгалтерии" Тогда
            Набор = РегистрыБухгалтерии[ИмяРегистра].СоздатьНаборЗаписей();
        ИначеЕсли ТипРегистра = "РегистрСведений" Тогда
            Набор = РегистрыСведений[ИмяРегистра].СоздатьНаборЗаписей();
        ИначеЕсли ТипРегистра = "РегистрРасчета" Тогда
            Набор = РегистрыРасчета[ИмяРегистра].СоздатьНаборЗаписей();
        КонецЕсли;
        
        Если ТаблицаДвижений <> Неопределено Тогда
            Набор.Загрузить(ТаблицаДвижений);
        КонецЕсли;
    КонецЕсли;
    
    Набор.Отбор.Регистратор.Установить(Регистратор);
    Набор.Записать();                                    // ТУТ ТАЙМАУТ (Когда "РегистрБухгалтерии.Хозрасчетный" )
    
КонецПроцедуры

Может не удалять движения по БУ ? Чем это чревато ?
1 vicof
 
22.05.14
12:01
казалось бы, при чем тут блокировки.
2 Alex_MA
 
22.05.14
12:13
(1)я понимаю, что у РБ по сути одно измерение "Организация", т.о. выполняя:

Набор.Записать(); - в начале транзакции мы исключительно блокируем до окончания транзакции!
В добавок ко всему есть запрос в обработке проведения, который медленно выполняется => длинная транзакция!

Нахрена так писать ?
3 hhhh
 
22.05.14
12:22
(2) уже миллион раз обсасывали

чтобы эти движения не повлияли на проведение.
4 Рэйв
 
22.05.14
12:24
(0)Используй управляемые блокировки в начале проведения и будет тебе щастье.
5 Alex_MA
 
22.05.14
12:30
(3)скиньте пожалуйста ссылку
6 Alex_MA
 
22.05.14
12:32
(4)Каким образом ? Ведь при:

Набор.Отбор.Регистратор.Установить(Регистратор);
Набор.Записать();

и так накладывается неявная исключительная блокировка (правда по всем записям регисра бухгалтерии, где организация = организации документа)
7 Alex_MA
 
22.05.14
12:33
(6)+ и накладываются избыточные блокировки (т.е. на все записи по организации - включая записи по тек. регистратору)
8 Рэйв
 
22.05.14
12:38
>>правда по всем записям регисра бухгалтерии, где организация = организации документа

Вот именно. А если сделаешь управляемую блокировку, то блокироваться будет только по указанному набору, а не все .
9 Рэйв
 
22.05.14
12:39
и чтобы наборы пересеклись одновременно при проведении - это исчезающе малая вероятность
10 Alex_MA
 
22.05.14
13:44
(9)

БлокировкаДанных = Новый БлокировкаДанных;
ЭлементБлокировки = БлокировкаДанных.Добавить("РегистрСведений.ДанныеЗакупок");
ЭлементБлокировки.УстановитьЗначение("Регистратор", Ссылка);
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
БлокировкаДанных.Заблокировать();

выдает ошибку

{Документ.ПриходнаяНакладная.МодульОбъекта(19)}: Ошибка при вызове метода контекста (Заблокировать)
        БлокировкаДанных.Заблокировать();
по причине:
У пространства блокировок РегистрСведений.ДанныеЗакупок не существует поля с именем Регистратор
У пространства блокировок РегистрСведений.ДанныеЗакупок не существует поля с именем Регистратор

Где ошибка ???
11 Alex_MA
 
22.05.14
13:50
Во, так работает:

БлокировкаДанных = Новый БлокировкаДанных;
        ЭлементБлокировки = БлокировкаДанных.Добавить("РегистрСведений.ДанныеЗакупок.НаборЗаписей");
        ЭлементБлокировки.УстановитьЗначение("Регистратор", Ссылка);
        ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
        БлокировкаДанных.Заблокировать();
12 Alex_MA
 
22.05.14
14:03
Набор.Отбор.Регистратор.Установить(Регистратор);
Набор.Записать();

На практике выходит что по умолчанию блокирует все записи по измерениям (всю таблицу по измерению организация по значению реквизита регистратора организация)?

Какова вообще гранулярность блокировки это оператора ?
13 Alex_MA
 
23.05.14
13:36
(8)такой подход не решает проблемы, т.к. все таки программа сама не явно устанавливает исключительную блокировку по набору записей - по регистратору.

Видимо на момент обновления, где то происходит запрос к хозрасчетному (в том числе в запрос попадают и заблокированные записи регистра по регистратору) - в результате таймаут
14 Alex_MA
 
23.05.14
13:40
(3) покажите тему где обсасывалось ?
15 Рэйв
 
23.05.14
13:41
16 Alex_MA
 
23.05.14
14:59
(15)это не из этой оперы. это дедлоки.
17 hhhh
 
23.05.14
15:02
(13) она сама себя не может заблокировать. Зачем блокировка?
18 Alex_MA
 
23.05.14
15:03
(17)согласен
19 hhhh
 
23.05.14
15:08
(18) элементарный пример: остаток товара на складе = 1 шт.

Документ реализация допустим дата 21.05 списывает одну шт.

Например пользователь меняет дату документа на 22.05.


Если мы не сотрем движения реализации, а они остались с датой 21.05, то она же при проведении увидит остаток на 22.05 = 0 и вообще не проведется.
20 Alex_MA
 
26.05.14
09:27
(19)вообще проанализировал код в обработке проведения платежных документов - остаток по хозрасчетному только в одном месте проверяется (но по условию в этот блок проверки остатков программа не заходит). Получается, что движения по хозрасчетному даже можно и не очищать. Ведь так ???
21 MrStomak
 
26.05.14
09:51
(16) А у тебя разве не дедлоки?
22 Alex_MA
 
26.05.14
09:59
(21)нет
23 MrStomak
 
26.05.14
10:02
(22) Почему пишешь про конфликт блокировок тогда? В чем проблема того, что однородные документы параллельно не проводятся? Почему думаешь на хозрасчетный, а не на последовательность, например, где действительно гранулярность по организации, в отличие от хозрасчетного? Непонятно вообще как твоя мысль там идёт, плохо описал.
24 Alex_MA
 
26.05.14
10:10
(23)>>Почему пишешь про конфликт блокировок тогда - потому что когда запрос отваливается по таймауту это тоже конфликт блокировок

>>Почему думаешь на хозрасчетный
потому что проверил - снял галку БУ и проводил документы - проводятся и перепроводятся
25 Alex_MA
 
26.05.14
10:13
(23)+ сдвиг последовательности в реал тайме у нас не производится.

У хозрасчетного два измерения "Организация" и "ВалютаРегУчета". Т.к. валюта у нас одна => узкое место по организации.

А разве можно блокировать регистр бухгалтерии по счетам ? Ведь счет - не является измерением таблицы. Если можно то не могли бы вы обосновать почему ?
26 MrStomak
 
26.05.14
10:28
(25)Я не понимаю, как был заключен вывод о конфликте блокировок. Если сообщение про таймаут выскакивает, то крайне подозрительно, что документ проводится и держит блокировку более 20 секунд, начинать надо с этого расследование.

"Измерение" - это не тот термин, с которым удобно залазить в тему блокировок.
На уровне СУБД есть поля, индексы, строки. Если есть запрос, выбирающий все записи по счету, то все они и будут заблокированы. Если запрос выбирает записи по организации, то заблокированы будут они. Если запрос выбирает только записи по регистратору (при удалении движений), то заблокированы будут только они. Ну понятно что есть таблица итогов, он в ней, само собой, есть поле "Счет" и даже более того - есть разделитель, позволяющий её парралельно писать.

Если говорить про уровень 1С и управляемые блокировик - то гранулярность описана в СП, она вплоть до субконто идёт.
27 MrStomak
 
26.05.14
10:40
(24) Судя по "галочке БУ" речь идёт про УПП/КА (почему сразу то не написать?). Ну так там взаиморасчеты построены на регистрах и просто отражаются в бухгалтерии, все запросы для аванса и т.д. выполняются не по РБ. РБ тут не может быть узким местом, разве что его блокирует что-то третье.
28 Alex_MA
 
26.05.14
10:47
(27)я в написал в (0) :)
29 MrStomak
 
26.05.14
10:48
(28) У меня избирательное зрение, надо было выше написать!:)
30 Alex_MA
 
26.05.14
10:48
(27)вот именно - нашел что блокирует. Это удаление движений по хозрасчетному

Набор.Отбор.Регистратор.Установить(Регистратор);
    Набор.Записать();                                    // ТУТ ТАЙМАУТ (Когда "РегистрБухгалтерии.Хозрасчетный" )
31 MrStomak
 
26.05.14
10:51
(30) Это запрос-жертва. Но кто виновник? Кто 20 секунд держит РБ? Обмен какой-нибудь поди?
Если ты уберешь удаление движений РБ, то один фиг получишь тот же самый таймаут, когда будешь писать его.
Проведение документов - оно надеюсь не в одной транзакции происходит?
32 acsent
 
26.05.14
10:53
упп без отложенного проведения практически не жизнеспособна
33 MrStomak
 
26.05.14
10:57
(32) В erp 2.0 на этом отложенном проведении в рег. заданиях все тяжелые участки сделаны, без каких-либо вариантов.
34 Alex_MA
 
26.05.14
10:58
(31)обмена нет. Настроил просто перепроведение документов в двух сеансах по ответственным.

по замеру вот два толстых места:

1) "РегистрБухгалтерииНаборЗаписей.Хозрасчетный"
таймаут


Ошибка при выполнении обработчика - 'ОбработкаПроведения'
по причине:
{ОбщийМодуль.ПолныеПрава.Модуль(1312)}: Ошибка при вызове метода контекста (Записать)

по причине:
Конфликт блокировок при выполнении транзакции:
Превышено максимальное время ожидания предоставления блокировки

2) таймаут при выполнении запроса:


ВЫБРАТЬ
    РасчетыВУЕ.ДоговорКонтрагента,
    РасчетыВУЕ.Сделка,
    РасчетыВУЕ.СчетОплаты,
    РасчетыВУЕ.ДатаОплаты КАК ДатаОплаты,
    РасчетыВУЕ.Документ КАК Документ,
    РасчетыВУЕ.СуммаВзаиморасчетовОстаток * &Множитель КАК СуммаВзаиморасчетов,
    РасчетыВУЕ.СуммаРегОстаток * &Множитель КАК СуммаРег
ИЗ
    РегистрНакопления.РасчетыПоРеализацииВУсловныхЕдиницахОрганизации.Остатки(
        &Период,
        (ДоговорКонтрагента, Сделка, СчетОплаты) В (ВЫБРАТЬ РАЗЛИЧНЫЕ ДоговорКонтрагента, Сделка, СчетОплаты ИЗ ТаблицаДляОстатковПоРегистру)) КАК РасчетыВУЕ
ГДЕ
    РасчетыВУЕ.СуммаВзаиморасчетовОстаток * &Множитель > 0
    И РасчетыВУЕ.СуммаРегОстаток * &Множитель > 0

ДЛЯ ИЗМЕНЕНИЯ
    РегистрНакопления.РасчетыПоРеализацииВУсловныхЕдиницахОрганизации.Остатки

УПОРЯДОЧИТЬ ПО
    ДатаОплаты,
    РасчетыВУЕ.Документ.Дата,
    Документ

БухгалтерскийУчетРасчетовСКонтрагентами, стр.1959


Но в основном до п.2) дело не доходит - таймаут  {ОбщийМодуль.ПолныеПрава.Модуль(1312)}: Ошибка при вызове метода контекста (Записать)

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

Проведение всех документов не в одной транзакции :)))
35 Alex_MA
 
26.05.14
10:59
(32)что так плохо написали то ?
не читали рекомендации с ИТС что ли ?
36 erp20
 
26.05.14
11:18
(32) Не обобщайте. Я в 2009 году наблюдал практически типовую УПП с 200 единовременно работающими пользователями в автоматическом режиме управления транзакциями! Большая часть из пользователей, работавших в системе формировала продажные цепочки (в стиле СНТ из КИП).
37 acsent
 
26.05.14
11:29
(35) ты про какие рекомендации?
38 Alex_MA
 
26.05.14
11:37
(37)ну например запись движений оставлять как можно ближе к концу транзакции
39 acsent
 
26.05.14
11:50
(38) Чем тебе это поможет, когда блокировка возникает на удалении движений, которое обязательно в начале процедуры?
40 acsent
 
26.05.14
11:51
(36) Ты видел 1 работающую, а я 100500 не работющих ))
41 Alex_MA
 
26.05.14
11:54
(39)тем, что на этот промежуток времени  не будет блокировок.
И вообще эту ф-ю очистки тогда можно модифицировать. Проанализировать документы и в зависимости от типов документов очищать или не очищать движения.

В 1С поступили универсально - что плохо повлияло на параллельность.
42 erp20
 
26.05.14
13:37
(40) Естественно. Умельцев то много.