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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 04.07.2025, 15:35   #1  
Lankey is offline
Lankey
Участник
 
159 / 30 (2) +++
Регистрация: 19.05.2020
createUserSessions - как работает?
AX2009 . В хранимой процедуре createUserSessions на стороне sql есть параметр @maxClientId
Кто-нибудь знает, откуда он берет значение(что означает)?
Проблема в том, что номера неактивных сессий (Status=0) в таблице SysClientSessions должны , судя по алготитму, отдаваться новым сессиям
Вот этот момент выбора:
X++:
select @first = min(sessionID)
from SysClientSessions with(UpdLock, readpast) 
where sessionId>@maxClientId
and SessionId <>@masterId
, но почему-то вместо этого создаются новые, и из-за этого растет таблица SysClientSessions .... Думаю, что дело в @maxClientId

Спасибо

Последний раз редактировалось Lankey; 04.07.2025 в 15:37.
Старый 05.07.2025, 08:17   #2  
Pandasama is offline
Pandasama
Участник
 
465 / 140 (5) +++++
Регистрация: 11.08.2014
Адрес: Барнаул
Сам не в курсе, но беглый гуглинг нашёл обсуждение этого параметра здесь
https://community.dynamics.com/forum...9-a2de0b0dfa90
Который дает ссылку сюда:
https://learn.microsoft.com/en-us/pr...ation-commands
Где есть параметр MaxConcurrentSessions

Возможно, это как-нибудь поможет
Старый 08.07.2025, 12:24   #3  
Lankey is offline
Lankey
Участник
 
159 / 30 (2) +++
Регистрация: 19.05.2020
Спасибо. Да, я видела ссылку на это обсуждение, но там нет ответа на вопрос. И у нас такая же проблема как там. ClientType=5 не переиспользует номера неактивных сессий, а создает новые
Старый 08.07.2025, 20:30   #4  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,983 / 3273 (117) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
А какую это создает проблему ?
Больше чем 65 тысяч записей не будет.

Какую проблемы вы решаете ?
Старый 11.07.2025, 17:55   #5  
Lankey is offline
Lankey
Участник
 
159 / 30 (2) +++
Регистрация: 19.05.2020
Постоянно падали все аосы. То один то другой. По рандому. Обнаружилось, что в этой таблице последняя активная запись с номером 65535 (в момент падения, естественно, становилась неактивной). В таблице записей было намного меньше (пару тысяч), чем 65535. Активных записей из них обычно около 100--200. Судя, по алгоритму, он падал как раз , тк больше 65535 присвоить не мог, но почему-то это сдедать пытался, вместо того, чтобы использовать неактиыне записи с SessionID ниже этой.

Перестарт АОС-ов дело не лечил. После какого-то времени все равно начинали рандомно падать АОСы
Вылечилось основкой всех АОСов и удалением записей из таблицы. Но не ясно, как так получилось, что максимум был достигнут и приводил к таким последствиям?

Последний раз редактировалось Lankey; 11.07.2025 в 18:05.
Старый 14.07.2025, 12:09   #6  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,715 / 1204 (44) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Штатное поведение - это как раз создание новых записей, а не использование "свободных". Если сессию перестали использовать, то она должны быть закрыта (удалена запись) и никак иначе

Там же дальше в хранимке [dbo].[CREATEUSERSESSIONS] возвращает код ошибки

X++:
select @first = min(SESSIONID) 
from SYSCLIENTSESSIONS WITH (UPDLOCK,READPAST) 
where STATUS = 0 
	and SESSIONID > @maxClientId 
	and SESSIONID <> @masterId 
	
if (select count(*) from SYSCLIENTSESSIONS where SESSIONID IN (@first)) > 0 
begin 
    (...)
     update (...)
     (...)
     select @sessionid = @first
end
else
begin 
	(...)
		select @max_val = max(SESSIONID)+1 
		from SYSCLIENTSESSIONS WITH (UPDLOCK) 
				
	if (@max_val > 65535) 
		select @sessionid = -3 
	else 
	(...)
end

Т.е. может быть только одна запись с номером сессии 65535. Номер больше создать не даст. Будет ждать, пока не уменьшат количество сессий (я смотрел в dax2012, возможно, в dax2009 этого условия нет)

В хранимке [dbo].[CREATEUSERSESSIONS] использование этих сессий - это исключение. Попытка как-то исправить проблему, передав сессию пользователю в надежде, что по завершении работы эта сессия будет корректно закрыта


Не вполне ответ на Ваш вопрос, но

Закрыть AxaptaCOMConnector из AXAPTA

В принципе, вывод тот же, что и в обсуждении https://community.dynamics.com/forum...9-a2de0b0dfa90

65535 - это предел. Максимум. Количество соединений должно быть меньше этого числа. Если соединения с номером больше этого числа вообще появились, то это ошибка. Их вообще надо отключать и сбрасывать и искать, почему такая ситуация возникла. Например, в обсуждении - это было подключение из-вне к Axapta. Ну и у меня по ссылке - тоже
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
За это сообщение автора поблагодарили: Logger (3).
Старый 15.07.2025, 10:21   #7  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,983 / 3273 (117) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Интересно.
У нас в этой табличке 65111 записей, но аос не падает. (Правда при остановке может задумываться с сообщениями о закрытии сессии с номером таким то и таких сообщений много. Надо будет перепроверить как идет закрытие сессии)

Аксапта 2012 R3
Старый 15.07.2025, 17:37   #8  
Lankey is offline
Lankey
Участник
 
159 / 30 (2) +++
Регистрация: 19.05.2020
Да. Он просто падает по этому условию, что Вы привели:
X++:
select @max_val = max(SESSIONID)+1 from SYSCLIENTSESSIONS WITH (UPDLOCK) 
if (@max_val > 65535) 
		select @sessionid = -3
(тк максимальное значение в таблице уже 65535, то он и падает).
Может, я не совсем понимаюю, что Вы хотели сказать, Владимир?
Я не понимаю, почему он не выбирает неактивные сессиии с меньшими номерами . Подозреваю, что это из-за передаваемого параметра @maxClientId

X++:
select @first = min(sessionID)
from SysClientSessions with(UpdLock, readpast) 
where sessionId>@maxClientId
and SessionId <>@masterId

Последний раз редактировалось Lankey; 15.07.2025 в 17:49.
Старый 15.07.2025, 18:31   #9  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,983 / 3273 (117) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
А у вас там своих кастомизаций нет ?
Может они влияют.

Я это к тому что у нас тоже дофига записей, почти 65536 но не падает.
Старый 15.07.2025, 22:49   #10  
Lankey is offline
Lankey
Участник
 
159 / 30 (2) +++
Регистрация: 19.05.2020
Цитата:
Сообщение от Logger Посмотреть сообщение
А у вас там своих кастомизаций нет ?
Может они влияют.

Я это к тому что у нас тоже дофига записей, почти 65536 но не падает.
Спасибо, но у меня к Вам вопросики
1) Если алгоритм хорошо работает, то как у вас дошло до таких высоких номеров? ( у вас же не так много одновременных соединений) . То есть, что к этом привело ?
2) И если дошло до 65111, то что мешает дойти и до 65535 (то есть, столкнуться с "нашей проблемой").
3) У вас запись с макс номером отдана активной сессий (Status =1)?
Старый 16.07.2025, 00:44   #11  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,983 / 3273 (117) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Где я говорил что алгоритм хорошо работает ? Меня тоже смущает такое множество записей, плюс аос явно тупит при остановке обрабатывая их.

Но у нас аос не падает.
Вот о чем речь.

Посмотрел сейчас рабочую, там максимальный номер 65535
Статус - Неактивный (Status = 0)
Тип сеанса - Business connector (clientType = 1)
LoginDateTime - 03.04.2023 15:06:58
Старый 16.07.2025, 00:49   #12  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,983 / 3273 (117) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Из свежих записей (у которых LoginDateTime - 15 июля) - самый большой номер 15886
Старый 16.07.2025, 01:03   #13  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,983 / 3273 (117) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
А вот код хранимки
Отформатирован тут
https://sqlformat.org/

X++:
CREATE PROCEDURE [dbo].[CREATEUSERSESSIONS] @clientType int, @sessionType int, @serverid int, @versionid int, @userid nvarchar(8),
                                                                                                                      @lanExt nvarchar(10),
                                                                                                                              @manExt nvarchar(10),
                                                                                                                                      @computerName nvarchar(80),
                                                                                                                                                    @sid nvarchar(124),
                                                                                                                                                         @recid bigint, @startId int, @maxusers int, @licenseType int, @masterId int, @maxClientId int, @dataPartition nvarchar(8),
                                                                                                                                                                                                                                                                       @sessionid int OUTPUT,
                                                                                                                                                                                                                                                                                      @loginDateTime datetime OUTPUT AS DECLARE @return_val AS int DECLARE @first AS int DECLARE @max_val AS int DECLARE @counter AS int BEGIN
SELECT @sessionid = -1
SELECT @max_val = -1
SELECT @counter = 0
SELECT @loginDateTime = dateadd(ms, -datepart(ms, getutcdate()), getutcdate()) if(NOT exists
                                                                                    (SELECT *
                                                                                     FROM SYSSERVERSESSIONS WITH (NOLOCK)
                                                                                     WHERE SERVERID = @serverid
                                                                                       AND Status = 1)) BEGIN
SELECT @sessionid = -2 RETURN END
SELECT @first = min(SESSIONID)
FROM SYSCLIENTSESSIONS WITH (UPDLOCK,
                             READPAST)
WHERE STATUS = 0
  AND SESSIONID > @maxClientId
  AND SESSIONID <> @masterId IF
    (SELECT count(*)
     FROM SYSCLIENTSESSIONS
     WHERE SESSIONID IN (@first)) > 0 BEGIN IF (@licenseType = 0) BEGIN
  UPDATE SYSCLIENTSESSIONS
  SET STATUS = 1,
      VERSION = @versionid,
                SERVERID = @serverid,
                USERID = @userid,
                LOGINDATETIME = @loginDateTime,
                SID = @sid,
                USERLANGUAGE = @lanExt,
                HELPLANGUAGE = @manExt,
                CLIENTTYPE = @clientType,
                SESSIONTYPE = @sessionType,
                CLIENTCOMPUTER = @computerName,
                DATAPARTITION = @dataPartition
  WHERE SESSIONID IN (@first) END ELSE IF (@licenseType = 1) BEGIN
  UPDATE SYSCLIENTSESSIONS
  SET STATUS = 1,
      VERSION = @versionid,
                SERVERID = @serverid,
                USERID = @userid,
                LOGINDATETIME = @loginDateTime,
                SID = @sid,
                USERLANGUAGE = @lanExt,
                HELPLANGUAGE = @manExt,
                CLIENTTYPE = @clientType,
                SESSIONTYPE = @sessionType,
                CLIENTCOMPUTER = @computerName,
                DATAPARTITION = @dataPartition
  WHERE SESSIONID IN (@first)
    AND (
           (SELECT count(SESSIONID)
            FROM SYSCLIENTSESSIONS
            WHERE CLIENTTYPE = @clientType
              AND ((STATUS = 1)
                   OR (STATUS = 2))) < @maxusers) END ELSE IF (@licenseType = 2) BEGIN
  UPDATE SYSCLIENTSESSIONS
  SET STATUS = 1,
      VERSION = @versionid,
                SERVERID = @serverid,
                USERID = @userid,
                LOGINDATETIME = @loginDateTime,
                SID = @sid,
                USERLANGUAGE = @lanExt,
                HELPLANGUAGE = @manExt,
                CLIENTTYPE = @clientType,
                SESSIONTYPE = @sessionType,
                CLIENTCOMPUTER = @computerName,
                DATAPARTITION = @dataPartition
  WHERE SESSIONID IN (@first)
    AND (
           (SELECT count(SESSIONID)
            FROM SYSCLIENTSESSIONS
            WHERE CLIENTTYPE = @clientType
              AND (USERID = @userid)
              AND ((STATUS = 1)
                   OR (STATUS = 2))) > 0
         OR
           (SELECT count(DISTINCT USERID)
            FROM SYSCLIENTSESSIONS
            WHERE CLIENTTYPE = @clientType
              AND ((STATUS = 1)
                   OR (STATUS = 2))) < @maxusers) END IF @@ROWCOUNT = 0
  SELECT @sessionid = 0 ELSE
  SELECT @sessionid = @first END ELSE BEGIN IF (@licenseType = 1) BEGIN IF
    (SELECT count(SESSIONID)
     FROM SYSCLIENTSESSIONS
     WHERE CLIENTTYPE = @clientType
       AND ((STATUS = 1)
            OR (STATUS = 2))) >= @maxusers
  SELECT @sessionid = 0 END ELSE IF (@licenseType = 2) BEGIN IF ((
                                                                    (SELECT count(DISTINCT USERID)
                                                                     FROM SYSCLIENTSESSIONS
                                                                     WHERE CLIENTTYPE = @clientType
                                                                       AND ((STATUS = 1)
                                                                            OR (STATUS = 2))) >= @maxusers)
                                                                 AND (
                                                                        (SELECT count(SESSIONID)
                                                                         FROM SYSCLIENTSESSIONS
                                                                         WHERE CLIENTTYPE = @clientType
                                                                           AND (USERID = @userid)
                                                                           AND ((STATUS = 1)
                                                                                OR (STATUS = 2))) = 0))
  SELECT @sessionid = 0 END IF (@sessionid = -1)
  OR (@licenseType = 0) BEGIN WHILE (@sessionid = -1
                                     AND @counter < 5) BEGIN
  SET @counter = @counter + 1 IF
    (SELECT count(SESSIONID)
     FROM SYSCLIENTSESSIONS WITH (UPDLOCK)
     WHERE STATUS = 0
       OR STATUS = 1
       OR STATUS = 2
       OR STATUS = 3) = 0
  SELECT @max_val = @startId ELSE
  SELECT @max_val = max(SESSIONID)+1
  FROM SYSCLIENTSESSIONS WITH (UPDLOCK) IF (@max_val > 65535)
  SELECT @sessionid = -3 ELSE BEGIN
  INSERT INTO SYSCLIENTSESSIONS(SESSIONID, SERVERID, VERSION, LOGINDATETIME, USERID, SID, USERLANGUAGE, HELPLANGUAGE, CLIENTTYPE, SESSIONTYPE, RECID, CLIENTCOMPUTER, STATUS, DATAPARTITION)
  VALUES(@max_val,
         @serverid,
         @versionid,
         @loginDateTime,
         @userid,
         @sid,
         @lanExt,
         @manExt,
         @clientType,
         @sessionType,
         @recid,
         @computerName,
         1,
         @dataPartition) IF @@ROWCOUNT = 0 BEGIN
  SELECT @sessionid = -1 END ELSE
  SELECT @sessionid = @max_val END END END END END
За это сообщение автора поблагодарили: Lankey (1).
Старый 16.07.2025, 02:50   #14  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,715 / 1204 (44) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Запустил SQL Profiler. Посмотрел, какое значение передано. У меня получилось следующее

До запуска Axapta в таблице SysClientSessions записи начинаются со значения SessionId = 3, первая запись со значением Ststus = 0 имеет SessionId = 6

При запуске Axapta фиксируется 2 вызова ХП (Имя компьютера и SID заменил текстом)

Вызов 1

@licenseType = 1
@masterId = 0
@maxClientId = 2

Код:
declare @p17 int
set @p17=6
declare @p18 datetime2(0)
set @p18='2025-07-15 22:21:38'
exec CREATEUSERSESSIONS 
	0,
	0,
	1,
	6,
	N'vmaksimo',
	N'RU',
	N'en-us',
	N'ComputerName',
	N'SID',
	5645806642,
	3,
	41750,
	1,
	0,
	2,
	N'initial',
	@p17 output,
	@p18 output
select @p17, @p18
Вызов 2

@licenseType = 0
@masterId = 6
@maxClientId = 6

Код:
declare @p17 int
set @p17=10
declare @p18 datetime2(0)
set @p18='2025-07-15 22:21:46'
exec CREATEUSERSESSIONS 
	3,
	1,
	1,
	6,
	N'vmaksimo',
	N'RU',
	N'en-us',
	N'ComputerName',
	N'SID',
	5645806643,
	3,
	30000,
	0,
	6,
	6,
	N'initial',
	@p17 output,
	@p18 output
select @p17, @p18
В итоге, в таблице SysClientSessions повторно используется запись с SessionId = 6. Т.е. отработал первый вызов ХП для @maxClientId = 2

Второй вызов ХП для @maxClientId = 6 тоже отработал, но потом это соединение было разорвано и у соответствующей записи возвращен Status = 0

Хм... Т.е. я был не прав. Это все-таки механизм повторного использования записи. Вопрос только в том, как значение этого параметра определяется.

Вероятно, для @licenseType = 1 просто как min()-1 по всей таблице. Для @licenseType = 0 уже как-то сложнее

Да, если запустить второй экземпляр Axapta не закрывая первый, то вызов будет с тем же параметром @maxClientId = 2
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...

Последний раз редактировалось Владимир Максимов; 16.07.2025 в 03:04.
Старый 16.07.2025, 13:54   #15  
Lankey is offline
Lankey
Участник
 
159 / 30 (2) +++
Регистрация: 19.05.2020
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Запустил SQL Profiler. Посмотрел, какое значение передано. У меня получилось следующее
Спасибо, Владимир
Ваш эксперимент был при скольких АОСах и каких типах соединения?
У нас несколько AOS и соединения и от обычных юзеров. и батчей и бизнес-коннекторов.
Думаю, что от того, какой текущий Clienttype и SessionType , передаваемый @maxClientId может быть разным. Поэтому и эксперимнт должен быть намного сложнее, чтобы это как-то проверить.
Старый 16.07.2025, 14:00   #16  
Lankey is offline
Lankey
Участник
 
159 / 30 (2) +++
Регистрация: 19.05.2020
Цитата:
Сообщение от Logger Посмотреть сообщение
Тип сеанса - Business connector (clientType = 1)
Вы имеете ввиду clientType или SessionType?

Если посмотреть ClientType enum в 2009 , то там 4 значения
  • СOMObject
  • Client
  • Server
  • Workerthread

А в SessionType;
  • GUI
  • BC
  • Worker
  • WebUser

Может, я не на то смотрю?
Старый 16.07.2025, 14:02   #17  
Lankey is offline
Lankey
Участник
 
159 / 30 (2) +++
Регистрация: 19.05.2020
Цитата:
Сообщение от Logger Посмотреть сообщение
А вот код хранимки
Спасибо большое. Сравню с нашей

PS Кастомизаций нет у нас, что писали бы напрямую в эту таблицу (вы спрашивали об этом ранее)
Старый 17.07.2025, 11:34   #18  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,983 / 3273 (117) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Lankey Посмотреть сообщение
Вы имеете ввиду clientType или SessionType?
опечатался похоже

Посмотрел еще раз
поле clientType (Тип сеанса) значение числовое 1 (Business Connector)
поле SessionId значение числовое 65535
поле sessionType значение числовое 0
поле Status (Статус) значение числовое 0 (Неактивный)
поле LoginDateTime значение 03.04.2023 15:06:58

clientType, sessionType, Status это конечно системные енумы.
Значения я думаю со своими сможете сопоставить.

Но не забывайте что у нас 2012-я

могут и отличия быть.

Последний раз редактировалось Logger; 17.07.2025 в 11:38.
Теги
ax2009

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
select crossCompany и Views - работает только для админов? DTD DAX: Программирование 11 26.03.2014 09:08
Всегда ли правильно работает queryrun().query().dataSourceCount() при присоединении пользователем таблиц в настройках стандартного запроса? Aquarius DAX: Программирование 5 26.09.2013 09:52
AX 2012 Enterprise Portal: Не работает Add indicators в Business Overview Web Part Maxim Gorbunov DAX: Администрирование 1 07.07.2012 14:49
Не работает поиск в лукапе на ГТД Bega DAX: Функционал 0 08.12.2011 09:09
почему на работает common.(fieldId)[idx] maze DAX: Программирование 3 31.08.2007 06:48

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

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

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