|
v7: SQL, блокировки, два ствола | ☑ | ||
---|---|---|---|---|
0
Phil_McLaren
04.12.13
✎
15:41
|
Доброго!
Прошу совета в следующей ситуации. Есть некая обработка на 77, чертовски большая и сложносочиненная, в которой в некоторый момент в ряде случаев вызывается процедура создания документов из сторонних входящих данных. Существующие документы ей никогда не перепроводятся, а создаваемых обычно от 1 до 20 в пределах одной сессии работы. Единственный типовой среди них - реализация. /*код целиком не привожу сознательно, одна только обсуждаемая процедура содержит больше 1000 строк, будет тяжело там отделить зерна от плевел*/ Вот прошел сбор и корректировка входных данных, начали в цикле обрабатывать коллекцию, которая эти данные теперь содержит в готовом для формирования документов виде. После создания и заполнения каждый документ записывается и проводится в отдельной транзакции. Проблема: периодически N документов не удается провести из-за блокировки SQL ('...deadlocked on lock resources with another process and has been chosen...' и дальше по тексту), причем в совершенно беспорядочном на первый взгляд виде - может быть из 6 вылетит блокировка на 1ый и 4ый, может быть из 10 на 2ой, может из 15 ни на один. Дальше интереснее. Если я обнаруживаю проблему, например, через минуту, и на основании тех же входных данных повторяю то же самое - транзакция проходит. Это привело меня к попытке сделать искусственный таймаут при проведении: исходная процедура вызывает процедуру проведения вида Функция ПровестиВТранзакции(Док) Попытка НачатьТранзакцию(); Док.Записать(); ЗаписьВЛог("Документ "+Строка(Док)+" записан",1); Результат=Док.Провести(); ЗафиксироватьТранзакцию(); Исключение ЗаписьВЛог("Документ "+Строка(Док)+": "+ОписаниеОшибки(),1,1); ОтменитьТранзакцию(); КонецПопытки; Возврат Результат; КонецФункции , и, если документ не проведен, ждет одну секунду и пытается провести еще раз, вплоть до 10 попыток. Это не помогло - все 10 попыток в каждом таком случае попадают в такую же взаимоблокировку. Следующий же документ вполне может провестись. А может быть то же самое. Картина усложняется тем обстоятельством, что я ограничен во времени выполнения, а данная процедура является лишь малой долей функционала обработки в плане нагрузки на учетную систему (и, следовательно, времени выполнения), так что делать таймаут минуту повторять весь цикл обработки входных данных с нуля я не могу. В высшей степени признателен за любое внимание проблеме и идеи по ее решению. |
|||
1
Тьма
04.12.13
✎
15:46
|
Собирай эти документы в кучку и пытайся их провести раз в несколько минут по паре штучек с помощью обработки ожидания, пока не закроешь весь список. Если используешь данные этих документов в последующих расчетах обработки - перепиши обработку.
|
|||
2
Phil_McLaren
04.12.13
✎
15:54
|
>>Собирай эти документы в кучку и пытайся их провести раз в несколько минут по паре штучек
А в чем преимущество по сравнению с последовательным проведением каждого в отдельной транзакции? >>Если используешь данные этих документов в последующих расчетах обработки Нет, мне сразу после обработки входных данных нужно сделать некоторые записи о результате работы и я забываю об этих документах. |
|||
3
Phil_McLaren
04.12.13
✎
15:54
|
+спасибо за ответ
|
|||
4
DeiMos
04.12.13
✎
15:57
|
Пиши не в лог, а куда-нибудь в другое место (файлег).
|
|||
5
ADirks
04.12.13
✎
16:46
|
Для начала неплохо бы выяснить, кто кого там блокирует, например такой штукой http://www.softportal.com/software-1058-sql-monitor.html
Как вариант решения проблемы: сначала все документы записывать, и только потом проводить, пока не проведутся. Ссылки на записанные документы запихивать, например, в спец.справочник, по мере проведения ссылки удалять. |
|||
6
Тьма
04.12.13
✎
16:51
|
(2)В том что в данный момент база заблокирована, а через пару минут может освободиться.
|
|||
7
Builder
04.12.13
✎
17:11
|
А смысл проведения документа в транзакции?
Она же и так сама в транзакции делается.... И как сделано ожидание 1 секунды? |
|||
8
ikea
04.12.13
✎
17:11
|
Обработка проводит документы в тот момент, когда заблокированы данные. У тебя же написано, что дедлок, значит ВЗАИМНАЯ блокировка. Скорее всего, у тебя документ при проведении считывает где-то данные, которые заняты другим пользователем. Посмотри, если есть в отчетах и модуле проведения SELECT, то поставь обязательно with(nolock).
|
|||
9
ikea
04.12.13
✎
17:13
|
Либо параллельно обработка и другой пользователь проводит документ, тут ты ничего уже не сделаешь. Запускай обработку в другое время.
|
|||
10
Господин ПЖ
04.12.13
✎
17:14
|
>В том что в данный момент база заблокирована, а через пару минут может освободиться.
блокирует ее кто? святой дух? что qa+профайлер говорят? |
|||
11
Злой Бобр
04.12.13
✎
18:42
|
(0) Попытка, транзакция - вы ребята как в детском саду. Может вы еще и запрос в цикле считаете нормальным?.. Боюсь увидев весь ваш шедевральный код мой мозг этого б невыдержал.
Посмотрите профайлер что именно блокирует. Вполне возможно что вы сами себе на яй** наступаете. А может кто и другой. Поймите одно - по фотографии такое нелечится. И само тоже непройдет. Так что или разгребайте сами, или пригласите программиста. И ненужно фыркать что вы типа тоже программисты. Все мы чего-то незнаем. Вы задавайте конкретные вопросы и мы пнем вас в правильном направлении. Просто когда вы говорите что что-то делаете и неработает - нам это ничего неговорит. |
|||
12
Phil_McLaren
05.12.13
✎
11:32
|
(11) Думаю, я задал вполне ясный вопрос, достаточно емко описав картину происходящего. У Вас, уважаемый, кажется, много демонов в голове: всегда думал, что если когда-нибудь свихнусь от 1С, то основным симптомом будут фразы типа "когда вы говорите что что-то делаете и неработает - нам это ничего неговорит"
(4) лог у меня ведется как файловый, так и в SQL базе, с ним все в порядке, только по нему и восстанавливаю картину. (5) Вот сначала записывать это вариант, пожалуй. (6) Разумно конечно, но приведенная функция проведения в транзакции вызывается, как я упоминал, циклически с интервалом в 1 секунду, и я могу делать это даже 30 секунд к ряду и каждый раз получать блокировку, а уже на следующем документе получить нормальное проведение. (7) Смысл в том, чтобы при помощи Rollback можно было отказаться от сделанных изменений, если общий результат операции неверен. В данном случае я отказываюсь прежде всего от записи документа, который не смогу провести. А ожидание сделано через ping. (8) Немного не сходится с тем фактом, что блокируется, например, 12ый документ из 20 - все одного вида, все двигают одни регистры, могут даже все быть на одного контра и разные даты. (10) с профайлером не удалось поработать - попробовал подержать трассировку по шаблону Locks (я не очень в профайлере уверенно себя чувствую и потому решил воспользоваться шаблоном), но ошибка с блокировкой совершенно непредсказуема и вызвать ее искусственно я не могу, так что пришло держать профайлер включенным где-то с час. За это время ни одной блокировки не вылетело, зато вылетели несколько терминальных пользователей |
|||
13
Simod
05.12.13
✎
11:42
|
(12) Транзакция на отдельный документ не имеет смысла - система по умолчанию выполняет проведение в транзакции. Если хочешь, чтобы не выпадали документы (12-й из 20-и), то проводи их все в одной транзакции. Или партиями (10, 100, ..).
|
|||
14
Phil_McLaren
05.12.13
✎
11:54
|
(13) хм, хорошо. Ты уверен, что группой будет надежнее, и я не потеряю все из-за блокировки при проведении одного? Я не прошу никаких гарантий, просто мне такое изначально казалось самой опасной реализацией, так что немного сомнения терзают
|
|||
15
пипец
05.12.13
✎
11:57
|
(14) проводили пачками с паузой (можно с отметкой о проведении ... в какой то момент ставить флаг , например в четный день 2-ку в нечетный 1, или вообще порядковый день года/что разумнее/) , дедлоки никуда не уйдут , просто многие смежные вещи придется пересмотреть через попытку исключение
ЗЫ рекомендовал бы еще 1с++ |
|||
16
пипец
05.12.13
✎
11:58
|
+ пауза была в виде пустого цикла между зафиксировать и начать транзакцию
|
|||
17
Simod
05.12.13
✎
12:03
|
(14) Если проведется первый документ, то проведутся и все остальные, т.к. из-за твоей транзакции никто не сможет "вклинится". Естественно, документ может не провестись по какой-либо другой причине. Например - нехватка товара. Тогда необходимо принимать решение - отмена всей транзакции или пропуск непроведенного документа и продолжение проведения остальных документов.
Разумеется это не все подводные камни. |
|||
18
Phil_McLaren
05.12.13
✎
12:15
|
(15), (17)
понял. Попробую так реализовать, отпишу о результате. Спасибо за помощь. |
|||
19
Холст
05.12.13
✎
14:10
|
(0) одна только обсуждаемая процедура содержит больше 1000 строк
- будь мужиком, начни с рефакторинга |
|||
20
Phil_McLaren
05.12.13
✎
15:16
|
(19) -)) справедливо) Там в принципе довольно чистенький код, имело бы смысл в какой-то момент взяться за полный пересмотр структуры и пообрезать углы, но сейчас нужно бесперебойную работу обеспечить.
В общем мы все через это проходили) |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |