AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 17.05.2006, 12:44   #1  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,953 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Мертвые блокировки при резерве
Добрый день, всем.

Разбирал недавно код Аксапты - однако много думал :-(

Кратко :
Есть проблема - возникают мертвые блокировки при резервировании по заказу. В системе создана функция которая в одной транзакции резервирует все строки по заказу. (Функция стартует по кнопке. При работе просто перебирает строчки и для каждой делает резерв. Порядок строк оставлен на усмотрение движка базы данных)

Мертвые блокировки возникли на таблице InventSum.

Первая догадка - мертвые блокировки возникают потому что при резервировании разных заказов номенклатуры в них перебираются в разном порядке. Например в одном Номенклатура1 затем Номенклатура2 а в это же время в другом заказе в обратном порядке Номенклатура2 затем Номенклатура1 - потенциально это с большой вероятностью приводит к мертвой блокировке в системе.

Чтобы этого избежать правильнее было бы везде при переборе строк заказа ставить сортировку по ItemId а также в классах ответственных за резервирование стараться чтобы аналитики перебирались в одном порядке.


Теперь, внимание! Самое интересное то, что в таблице SalesLine нет индекса в который бы входили поля SalesId, ItemId (и который был бы полезен для этих целей) Вместо него есть индекс SalesId, LineNum. Кроме того семейство классов SalesFormLetter и SalesTotals используют при переборе строк Query в котором сорировка стоит по LineNum.

Например, в SalesFormLetter.updateQueryBuild()
стоит
chooseLines.query().dataSourceTable(tableNum(SalesLine)).addSortField(fieldNum(SalesLine, salesId));
chooseLines.query().dataSourceTable(tableNum(SalesLine)).addSortField(fieldNum(SalesLine, lineNum));

Таким образом проблема блокировок может возникнуть даже при простой обработке заказа. ( Нам видимо до сих пор везло)


Вот я сижу и думаю, почему разработчики аксапты поставили везде сортировки по LineNum.
Может какая-то идея хитрая была. Мне вот кажется что для целей производительности лучше везде ставить сортировку по ItemId. Ну и еще для верности по аналитике.

Последний раз редактировалось Logger; 17.05.2006 в 13:02.
Старый 17.05.2006, 13:24   #2  
Wamr is offline
Wamr
----------------
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
1,737 / 858 (32) +++++++
Регистрация: 15.01.2002
Адрес: Москва
Записей в блоге: 7
Простое решение - сделать резервирование по всем строкам с транзакцией только на 1 строчку, а не весь заказ.
Старый 17.05.2006, 14:12   #3  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,953 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Wamr
Простое решение - сделать резервирование по всем строкам с транзакцией только на 1 строчку, а не весь заказ.
Не получится так.
Я тоже хотел для оптимизации сделать резерв по каждой строке в отдельной транзакции. Но по ряду причин требуют чтобы в одной транзакции было резервирование всех строк.

Кроме того для случая обработки заказа это не поможет. Там то все строки в одной транзакции обрабатываются - та же проблема будет. (Считаем что система множественных складских транзакций выключена)

Я вот никак не пойму, зачем было делать сортировку по LineNum.
Пока не вижу от этого никакой пользы.
Старый 17.05.2006, 14:33   #4  
Torin is offline
Torin
Участник
 
127 / 31 (2) +++
Регистрация: 10.03.2003
Адрес: Odessa, Ukraine
Хочу уточнить - термин "Мертвые блокировки" - это Deadlock в СУБД или что-то другое имеется ввиду ?
Если это он, то стоит рассказать про Базу и версию.
Хинты включены ? Стоить "догадки" про оптимизатор не стоит (там все намного сложнее), просто посмотрите какой индекс пользуется при выполнении запроса.
Напишите. подумаю.
Старый 17.05.2006, 14:54   #5  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,953 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Да, это DeadLock
Все хинты выключены.
База Оракл.
Версия Ax 3.0 sp3

Индекс оптимизатор может выбирать разный в зависимости от условий.
я подозреваю, что в случае резервирования он использует SalesLineIdx или SalesStatusIdx

Ну в принципе это уже не так важно.

Важно понять зачем разработчики навтыкали сортировок по LineNum в SalesFormLetter

Последний раз редактировалось Logger; 17.05.2006 в 14:58.
Старый 17.05.2006, 15:07   #6  
Torin is offline
Torin
Участник
 
127 / 31 (2) +++
Регистрация: 10.03.2003
Адрес: Odessa, Ukraine
А, ну вот я и пашел себе своей дорогой, раз Оракл ;-)
Сори, тут я некомпетентен.
Просто советую к специалистам "заходить" с планом выполнения запроса и статистикой по индексам. Иначе такой народ просто не будет помогать, термины "подозреваю" потусторонни в данном случае. Это из моего опыта тюнинга под Сиквел. Бывают очень даже неожиданные варианты.
Старый 17.05.2006, 15:29   #7  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,953 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Torin
А, ну вот я и пашел себе своей дорогой, раз Оракл ;-)
Сори, тут я некомпетентен.
Просто советую к специалистам "заходить" с планом выполнения запроса и статистикой по индексам. Иначе такой народ просто не будет помогать, термины "подозреваю" потусторонни в данном случае. Это из моего опыта тюнинга под Сиквел. Бывают очень даже неожиданные варианты.

Torin, мне кажется что вы невнимательно прочитали вопрос. Подобная проблема по идее должна возникать и в SQL2000
Движок базы данных не важен.

Если перебор идет по номерам строк, а товары набивались в разном порядке то
в заказе 1 номенклатуры могут перебираться так
Номенклатура1 затем Номенклатура2

а в заказе 2 :
Номенклатура2 затем Номенклатура1

Очевидно что независимо от базы данных при интенсивной работе вероятность мертвой блокировки высока.

А если при переборе строк сортировать по ItemId то мертвой блокировки возникнуть не может.

Вопрос в том почему в Аксапте стоит сортировка по LineNum. Из соображений оптимизации производительности напрашивается сортировка по ItemId.

Последний раз редактировалось Logger; 17.05.2006 в 15:32.
Старый 17.05.2006, 15:39   #8  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Что-то не понятно.
У вас сначала резервируется заказ1, затем заказ2 в одной транзакции, или резервирование происходит одновременно на разных машинах (в разных копиях Ax)?
__________________
Axapta v.3.0 sp5 kr2
Старый 17.05.2006, 15:48   #9  
ALES is offline
ALES
Участник
Злыдни
 
220 / 45 (2) +++
Регистрация: 11.08.2004
Цитата:
Сообщение от Logger
Вопрос в том почему в Аксапте стоит сортировка по LineNum. Из соображений оптимизации производительности напрашивается сортировка по ItemId.
Из соображений пользовательского интерфейса стоит lineNum, а о производительности "Damgaard" местами совсем не думал..
Старый 17.05.2006, 16:00   #10  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,953 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от AndyD
Что-то не понятно.
У вас сначала резервируется заказ1, затем заказ2 в одной транзакции, или резервирование происходит одновременно на разных машинах (в разных копиях Ax)?
У нас сидит хренова туча операторов - человек 20 а может и больше и фигачат заказы.

Так что заказ1 с одного рабочего места обрабатывается, а заказ2 с другого одновременно.
Вся фишка в том что с разных рабочих мест разные юзеры работают и друг друга блокируют намертво ...

Последний раз редактировалось Logger; 17.05.2006 в 16:33.
Старый 17.05.2006, 16:07   #11  
Torin is offline
Torin
Участник
 
127 / 31 (2) +++
Регистрация: 10.03.2003
Адрес: Odessa, Ukraine
Цитата:
Сообщение от Logger
Torin, мне кажется что вы невнимательно прочитали вопрос. Подобная проблема по идее должна возникать и в SQL2000
Движок базы данных не важен.

Если перебор идет по номерам строк, а товары набивались в разном порядке то
в заказе 1 номенклатуры могут перебираться так
Номенклатура1 затем Номенклатура2

а в заказе 2 :
Номенклатура2 затем Номенклатура1

Очевидно что независимо от базы данных при интенсивной работе вероятность мертвой блокировки высока.

А если при переборе строк сортировать по ItemId то мертвой блокировки возникнуть не может.

Вопрос в том почему в Аксапте стоит сортировка по LineNum. Из соображений оптимизации производительности напрашивается сортировка по ItemId.
Не совсем.
1) Реализация оптимизаторов настолько разная, что лучьше разбираться отдельно, и не держать " в уме"
2) Обход SalesLine по LineNum, кстати, очень логичен ;-) - все транзации движуться в одном направлении.
3) Вопрос в том, каким должен быть обход InventSum - очевидно, совсем другим ;-), как правильно замечено по аналитикам. Тут, конечно, сразу предполагаем, что
а) Блокируються и индексы и страницы данных поразному
б) Какие индексы, собственно, есть, потому что блокируються все (или нет - зависит от базы)
в) Каков план доступа к записи (если неправильный индекс, то дольше транзация и меньше параллелизм)
Например, у меня в InventSum есть индекс
DATAAREAID (ASC), ITEMID (ASC), INVENTDIMID (ASC)
Используется ли он ? Я не знаю. кластерного нет, хинтов нет, значит решает оптимизатор. Какой он выбрал ?. Какие еще индексы заблокируються ? Что именно заблокировано ? Последний, вопрос, кстати, самый важный - на чем дедлок ловиться. Посмотрите - подумаем дальше.
Старый 17.05.2006, 16:16   #12  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,953 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от ALES
Из соображений пользовательского интерфейса стоит lineNum, а о производительности "Damgaard" местами совсем не думал..
Почему вы так решили ?
Для пользователя можно в SalesTable на датасорсе указать индекс SalesLineIdx и она будет строчки по порядку показывать - да так по моему и сделали.
А при обработке можно использовать другой индекс.

Так что тут программисты не ограничены ничем и исправление делается в два счета.
Кроме того я бы не сказал что разработчики аксапты забили на производительность. Судя по коду на это не похоже.

Мне кажется что сортировка по LineNum имеет какой то смысл. Ну либо проглючили проггеры. С кем не бывает.
Старый 17.05.2006, 16:20   #13  
Atar is offline
Atar
Консультант
 
287 / 101 (4) +++++
Регистрация: 10.03.2006
Адрес: Москва
Вполне логично (с точки зрения пользователя системы) резервирование в порядке строк документа.
Старый 17.05.2006, 16:30   #14  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,953 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Atar
Вполне логично (с точки зрения пользователя системы) резервирование в порядке строк документа.
Интересно и в чем же логика ?
Старый 17.05.2006, 16:31   #15  
ALES is offline
ALES
Участник
Злыдни
 
220 / 45 (2) +++
Регистрация: 11.08.2004
Цитата:
Сообщение от Logger
Почему вы так решили ?
На основании опыта "лечения" c грохотом тормозящих решений на 2.5. В трешке многое изменилось, но "с нуля" ведь ее не переписали..
Старый 17.05.2006, 16:36   #16  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от Logger
Есть проблема - возникают мертвые блокировки при резервировании по заказу. В системе создана функция которая в одной транзакции резервирует все строки по заказу
Сколько (в среднем) строк в заказе - десятки, сотни?
Стандартный механизм (Заказ \ Настройки \ Резервирование = Автоматически) у Вас при этом нормально работает ? Если да - ну, Вы поняли..
__________________
-ТСЯ или -ТЬСЯ ?
Старый 17.05.2006, 16:45   #17  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,953 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Vadik
Сколько (в среднем) строк в заказе - десятки, сотни?
Стандартный механизм (Заказ \ Настройки \ Резервирование = Автоматически) у Вас при этом нормально работает ? Если да - ну, Вы поняли..
По разному в среднем порядка 40 строчек - ну так на глаз прикинул. Бывает и меньше по 5- 10 строк. Иногда больше - 200. Но это реже.

Авторезервирование не использовали.
У нас есть кнопка которую давит юзер и там просто перебираются строчки и для каждой идет резервирование с использованием InventUpd_reservation - все в одной транзакции.

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

Вообще то то эта проблема не всегда возникает а время от времени. Полагаю, просто что в этот момент сервер загружен вот и все. - Запросы медленнее выполняется - вероятность что пересекутся запросы ForUpdate от разных пользователей за один и тот же InventSum - гораздо выше - и пожалуйста принимайте готовенький DeadLock

Последний раз редактировалось Logger; 17.05.2006 в 16:48.
Старый 17.05.2006, 16:56   #18  
Recoilme is offline
Recoilme
злыдень
Аватар для Recoilme
Злыдни
 
895 / 192 (8) ++++++
Регистрация: 18.06.2003
но ведь если все в одной транзакции то какую роль может играть порядок сортировки?
тормозят запросы - их надо оптимизировать, думать не надо )
__________________
Ибо зло есть лучшая сила человека. "Человек должен становиться все лучше и злее" -- так учу я. /Ф. Ницше/
Старый 17.05.2006, 17:23   #19  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,953 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Recoilme
но ведь если все в одной транзакции то какую роль может играть порядок сортировки?
тормозят запросы - их надо оптимизировать, думать не надо )
Ну я же написал в самом начале. :-(
Работа с разными строчками идет в одной транзакции, а заказы - в разных обрабатываются с разных рабочих мест, но одновременно

Ну смотрите :

заказ 1
Строка 1 Номенклатура1
Строка 2 Номенклатура2

заказ 2
Строка 1 Номенклатура2
Строка 2 Номенклатура1

С одного рабочего места начинается транзакция, которая перебирает строки заказа1
обновила строку с номенклатурой1 и на соответсвующей InventSum повесила блокировку, так что другая транзакция не сможет получить её forUpdate ( на чтение прочитает, а forUpdate - фиг)

В это же время с другого рабочего места начинается другая транзакция которая обрабатывает заказ 2 обработала в нем строчку номер 1 в которой находится номенклатура 2 и в резульате по номенклатуре 2 повесила блокировку на InventSum, так что никакая другая транзакция не может получить её ForUpdate

А дальше первая транзакция пытается получить forUpdate InventSum с номенклатурой 2 - но не может и ждет завершения второй транзакции.
а вторая транзакция хочет отобрать forUpdate InventSum с номенклатурой 1 но не может, потому что на ней висит блокировка от первой транзакции. И поэтому вторая транзакция тоже ждет.

Вот так они друг друга ждут - классический DeadLock.

Он может длиться сколь угодно долго пока БД по таймауту не откатит одну из транзакций.

Эта фигня может возникать на сколь угодно можных серверах и сколь угодно оптимизированных запросах. Все дело в порядке перебора записей разными транзакциями.


А если мы будем перебирать строки заказа по ItemId то как не трудно заметить мертвой блокировки не получится.
Просто одна из транзакций успеет раньше заблокировать Номенклатуру 1 а другая транзакция подождет заверешения её работы вот и все.
Старый 17.05.2006, 17:25   #20  
Torin is offline
Torin
Участник
 
127 / 31 (2) +++
Регистрация: 10.03.2003
Адрес: Odessa, Ukraine
Logger, мы не сдвинемся с места, пока не скажете, участников дедлока, что они делали, и на каком уровне дедлок (запись, страница и т.п.). Подозреваю, что Оракл может также сказать на каком объекте и еще массу полезной информации.
Теги
ax3.0, блокировка, резервирование

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
SysSQLBlockingMSSQL - форма Блокировки пользователей базы данных DenisS DAX: Программирование 6 18.08.2009 17:23
блокировки таблицы WMTRANSFER_FACTUREJOUR. ipas DAX: Администрирование 0 29.09.2008 15:20
Блокировки на SQL при потере связи. Alexandr A. Osipkin DAX: Администрирование 8 25.04.2007 16:52
Блокировки с SalesParmTable DreamCreator DAX: Программирование 3 22.12.2005 14:27
Блокировки M.Ruslan DAX: Администрирование 8 27.04.2005 14:15

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 18:56.