|
Фоновые задания. Превышение времени предоставления блокировки | ☑ | ||
---|---|---|---|---|
0
Tateossian
24.09.14
✎
16:21
|
Уважаемые форумчане! Столкнулся со следующей проблемой. В некой функции строю дерево партий (из партионного учета) со всеми цепочками преобразований (через отчеты производства за смену, комплектации) - некий локальный расчет себестоимости. Переделал разузлование на фоновых заданиях, которые запускаются при уровне выше второго. Но во время работы фоновых заданий есть таблица, которая хранит в себе данные "цепочек" - с документом оприходования и документом списания и количеством. Данные в ней должны быть синхронизированы: сначала я читаю данные в этой таблице, потом записываю. Эта таблица сделана на непериодическом РС. И постоянно фоновые задания падают на методе Прочитать(). Как правильно разруливать блокировку? Там таблица из трех записей, вот же ж. И все равно падает.
|
|||
1
Tateossian
24.09.14
✎
16:23
|
Сделал вот такую штуку с блокировкой. может, не правильно?
Процедура НакопитьДвижение(ТаблицаНакопленных, Регистратор, ДокументПартии, Номенклатура, Количество) Блокировка = Новый БлокировкаДанных; ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.АА_НакоплениеДвиженийНДСЭкспорт"); ЭлементБлокировки.УстановитьЗначение("ДокументДвижения", Регистратор); ЭлементБлокировки.УстановитьЗначение("ДокументОприходования", ДокументПартии); ЭлементБлокировки.УстановитьЗначение("Номенклатура", Номенклатура); МенеджерЗаписи = РегистрыСведений.АА_НакоплениеДвиженийНДСЭкспорт.СоздатьМенеджерЗаписи(); МенеджерЗаписи.ДокументДвижения = Регистратор; МенеджерЗаписи.ДокументОприходования = ДокументПартии; МенеджерЗаписи.Номенклатура = Номенклатура; МенеджерЗаписи.Прочитать(); Блокировка.Заблокировать(); Если Не МенеджерЗаписи.Выбран() Тогда МенеджерЗаписи.ДокументДвижения = Регистратор; МенеджерЗаписи.ДокументОприходования = ДокументПартии; МенеджерЗаписи.Номенклатура = Номенклатура; МенеджерЗаписи.Количество = Количество; Иначе МенеджерЗаписи.Количество = МенеджерЗаписи.Количество + Количество; КонецЕсли; МенеджерЗаписи.Записать(); Блокировка = Неопределено; КонецПроцедуры |
|||
2
Tateossian
24.09.14
✎
16:31
|
(1) Это обрезанная функция, не обращайте внимания на параметр "ТаблицаНакопленных".
Вся эта механизма работает в рекурсии. Функция "НакопитьДвижение" вызывается из функции, где перед этим идет вот такой блок: Процедура ППП() // написал для форматирования СтруктураПоиска = Новый Структура("ДокументДвижения, ДокументОприходования, Номенклатура", ДокПартии, стрОстаток.Регистратор, стрОстаток.Затрата); МенеджерЗаписи = РегистрыСведений.АА_НакоплениеДвиженийНДСЭкспорт.СоздатьМенеджерЗаписи(); МенеджерЗаписи.ДокументДвижения = СтруктураПоиска.ДокументДвижения; МенеджерЗаписи.ДокументОприходования = СтруктураПоиска.ДокументОприходования; МенеджерЗаписи.Номенклатура = СтруктураПоиска.Номенклатура; МенеджерЗаписи.Прочитать(); Если МенеджерЗаписи.Выбран() Тогда лКоличествоОстаток = лКоличествоОстаток - МенеджерЗаписи.Количество; КонецЕсли; КонецЕсли; ... НакопитьДвижение(ТабНакопленных, ДокПартии, стрОстаток.Регистратор, стрОстаток.Затрата, лСписываем); КонецПроцедуры То есть, я сначала читаю остаток в этом регистре, потом его дописываю. Излишняя блокировка получается. |
|||
3
Tateossian
24.09.14
✎
17:36
|
Убрал процедуру НакопитьДвижение() и засунул все сюда (2)
Процедура ППП() // написал для форматирования СтруктураПоиска = Новый Структура("ДокументДвижения, ДокументОприходования, Номенклатура", ДокПартии, стрОстаток.Регистратор, стрОстаток.Затрата); МенеджерЗаписи = РегистрыСведений.АА_НакоплениеДвиженийНДСЭкспорт.СоздатьМенеджерЗаписи(); МенеджерЗаписи.ДокументДвижения = СтруктураПоиска.ДокументДвижения; МенеджерЗаписи.ДокументОприходования = СтруктураПоиска.ДокументОприходования; МенеджерЗаписи.Номенклатура = СтруктураПоиска.Номенклатура; МенеджерЗаписи.Прочитать(); Если МенеджерЗаписи.Выбран() Тогда лКоличествоОстаток = лКоличествоОстаток - МенеджерЗаписи.Количество; МенеджерЗаписи.Количество = МенеджерЗаписи.Количество + Мин(лНеобходимоСписать, лКоличествоОстаток); Иначе МенеджерЗаписи.ДокументДвижения = СтруктураПоиска.ДокументДвижения; МенеджерЗаписи.ДокументОприходования = СтруктураПоиска.ДокументОприходования; МенеджерЗаписи.Номенклатура = СтруктураПоиска.Номенклатура; МенеджерЗаписи.Количество = Мин(лНеобходимоСписать, лКоличествоОстаток); КонецЕсли; МенеджерЗаписи.Записать(); ... КонецПроцедуры Все равно падает... |
|||
4
Зойч
24.09.14
✎
17:47
|
режим блокировок какой?
|
|||
5
Tateossian
24.09.14
✎
17:48
|
(4) Управляемый, конечно.
|
|||
6
bolobol
24.09.14
✎
17:51
|
Если управления не получается, видимо - НЕуправляемый и НЕконтролируемый...
|
|||
7
Зойч
24.09.14
✎
18:06
|
интересно с другой стороны кто блокирует
|
|||
8
Зойч
24.09.14
✎
18:08
|
Попробуй
http://www.gilev.ru/setuplatch/ |
|||
9
Tateossian
25.09.14
✎
16:28
|
Апну ветку.
Господа! Я не уточнил, что это все делается в обработке проведения. Если эту функцию вывести отдельно, то все работает без проблем. Вопрос: почему в обработке проведения фоновые задания блокируются? У документа режим управления блокировкой выставил в управляемый. |
|||
10
bolobol
25.09.14
✎
16:52
|
Твою стипендию! С этого и начинать нужно было!
Сам себе заблокировал в транзакции проведения, а другим сеансом накладываешь тоже самое. |
|||
11
acanta
25.09.14
✎
16:52
|
А где то в настройках сеанса можно увеличить это время предоставления блокировки?
|
|||
12
Fragster
гуру
25.09.14
✎
17:46
|
(11) можно даже программно
|
|||
13
Fragster
гуру
25.09.14
✎
17:48
|
Глобальный контекст (Global context)
УстановитьВремяОжиданияБлокировкиДанных (SetLockWaitTime) Синтаксис: УстановитьВремяОжиданияБлокировкиДанных(<Таймаут>) Параметры: <Таймаут> (необязательный) Тип: Число. Время ожидания блокировки данных (в секундах). Значение по умолчанию: 20 Описание: Устанавливает время ожидания блокировки данных (в секундах). Доступность: Сервер, толстый клиент, внешнее соединение. |
|||
14
Tateossian
25.09.14
✎
18:23
|
(10) В том-то и загвоздка, что фоновым заданиям вообще пофиг на проводимую реализацию в родительском сеансе. Если убрать этот регистр, то фоновые задания отрабатываются нормально. Это регистр нужен для синхронизации данных, отрабатываемых разными фоновыми заданиями. Я тестировал без него - никаких проблем с блокировками. Выходит, вся проблема в данном регистре, но в родительском сеансе к нему нет обращений. ЧЯДНТ?
|
|||
15
Fragster
гуру
25.09.14
✎
18:39
|
документ подичиненый регистратору? удаление движений авто? в регистр пишешь в "родительском" сеансе?
|
|||
16
Tateossian
25.09.14
✎
18:41
|
(15) В смысле регистр? Не, неподчиненный. В родительском этот регистр вообще не используется. Кстати, заметил, что результаты, выполненные в одном потоке и асинхронно различаются. Не сильно, но разница есть. Походу, ошибка в логике где-то :(
|
|||
17
Fragster
гуру
25.09.14
✎
18:43
|
надеюсь, ты в обработке проведения не дожидаешься конца выполнения фоновых, а только их стартуешь, а уже они разруливают формирование движений и слитие результатов?
|
|||
18
Fragster
гуру
25.09.14
✎
18:46
|
концепт такой:
обработка проведения -> старт фонового задания 1 фоновое задание 1 - делим данные на независимые порции, стартуем фоновые задания 2...К на каждую порцию или не более чем Х штук в цикле пока порции не закончатся. ждем окончания Фоновые задания 2...К пишут в независимый регистр результаты своей работы фоновое задание 1 - собирает результаты, очищает регистр-буфер, записывает набор движений исходного документа. |
|||
19
Tateossian
25.09.14
✎
18:51
|
(18) ААААА, понял. У меня нет этого "прокси" - фонового задания 1. Кстати, можно подключить обработчик ожидания (имхается мне) и там стартануть все это дело. Но вот вопрос: а если будет эксепшн, как этот вопрос разрулить? (Движения тогда не запишутся)
|
|||
20
Fragster
гуру
25.09.14
✎
18:52
|
МенеджерФоновыхЗаданий (BackgroundJobsManager)
ОжидатьЗавершения (WaitForCompletion) Синтаксис: ОжидатьЗавершения(<ФоновыеЗадания>, <Таймаут>) Параметры: <ФоновыеЗадания> (обязательный) Тип: Массив. Массив фоновых заданий, завершение которых нужно ожидать. <Таймаут> (необязательный) Тип: Число. Таймаут в секундах ожидания завершения заданий. Если таймаут не задан, ожидание будет длиться до завершения всех заданий, или до первого аварийного завершения задания. Описание: Ожидает завершения всех фоновых заданий из списка. Если хотя бы одно задание завершено аварийно, ожидание прерывается и выдается ошибка выполнения задания. Если наступил таймаут, выдается ошибка ожидания задания. Ожидать завершения заданий может только администратор или пользователь, запустивший задания на выполнение. Доступность: Сервер, толстый клиент, внешнее соединение. |
|||
21
Fragster
гуру
25.09.14
✎
18:53
|
||||
22
Tateossian
25.09.14
✎
18:59
|
(20) Я как раз эту процедуру юзаю в обработке проведения. Если она выполнится, тогда отрабатываю данные, если "отваливается" провожу без фоновых заданий. Так вот после добавления этого регистра, обеспечивающего синхронизацию - она всегда отваливается. Даже одно фоновое задание нельзя запустить. Почему так?
|
|||
23
Fragster
гуру
25.09.14
✎
19:10
|
(22) забей на обработку проведения, делай все вне транзакции
|
|||
24
Fragster
гуру
25.09.14
✎
19:10
|
иначе будет косяк
|
|||
25
Fragster
гуру
25.09.14
✎
19:11
|
ну ты видимо юзаешь какие-то заблокированные ресурсы из незакрытой транзакции записи-проведения документа, и при этом сам себе дедлок делаешь
|
|||
26
Tateossian
25.09.14
✎
19:25
|
(25) Ок, я понял. А как проверить, что фоновое задание отработало нормально? Видится мне мне, что что-то вроде Пока Не проведенПравильно Цикл завернуть в попытку, а при исключении проведенПравильно = ложь и так до бесконечности:) Или ограничиться несколькими попытками и вывести в ЖР.
|
|||
27
Fragster
гуру
25.09.14
✎
19:41
|
в обработке проведения пиши в регистр ключ задания номер 1, в конце фонового задания пиши в регистр успех или косяк, далее - обрабатывай, либо в самом задании (при необходимости отменяй проведение, например), либо в обработке ожидания.
также передзаписью документа можно этот регистр проверять и блокировать. И в списке документов раскрашивать сереньким, допустим. |
|||
28
Fragster
гуру
25.09.14
✎
19:42
|
(27)+ только в случае косяка - надо не совсем отменять, а восстанавливать предыдущее состояние, что немного сложнее
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |