|  04.07.2025, 15:35 | #1 | 
| Участник | createUserSessions - как работает? 
			
			AX2009 . В хранимой процедуре createUserSessions на стороне sql есть параметр @maxClientId Кто-нибудь знает, откуда он берет значение(что означает)? Проблема в том, что номера неактивных сессий (Status=0) в таблице SysClientSessions должны , судя по алготитму, отдаваться новым сессиям Вот этот момент выбора: X++: select @first = min(sessionID) from SysClientSessions with(UpdLock, readpast) where sessionId>@maxClientId and SessionId <>@masterId Спасибо Последний раз редактировалось Lankey; 04.07.2025 в 15:37. | 
|  | 
|  05.07.2025, 08:17 | #2 | 
| Участник | 
			
			Сам не в курсе, но беглый гуглинг нашёл обсуждение этого параметра здесь https://community.dynamics.com/forum...9-a2de0b0dfa90 Который дает ссылку сюда: https://learn.microsoft.com/en-us/pr...ation-commands Где есть параметр MaxConcurrentSessions Возможно, это как-нибудь поможет | 
|  | 
|  08.07.2025, 12:24 | #3 | 
| Участник | 
			
			Спасибо. Да, я видела ссылку на это обсуждение, но там нет ответа на вопрос. И у нас такая же проблема как там. ClientType=5 не переиспользует номера неактивных сессий, а создает новые
		 | 
|  | 
|  08.07.2025, 20:30 | #4 | 
| Участник | 
			
			А какую это создает проблему ? Больше чем 65 тысяч записей не будет. Какую проблемы вы решаете ? | 
|  | 
|  11.07.2025, 17:55 | #5 | 
| Участник | 
			
			Постоянно падали все аосы. То один то другой. По рандому. Обнаружилось, что в этой таблице последняя активная запись с номером 65535 (в момент падения, естественно, становилась неактивной). В таблице записей было намного меньше (пару тысяч), чем  65535. Активных записей из них  обычно около 100--200.  Судя, по алгоритму, он падал как раз , тк больше 65535 присвоить не мог, но почему-то это сдедать пытался, вместо того, чтобы использовать неактиыне записи с SessionID ниже этой. Перестарт АОС-ов дело не лечил. После какого-то времени все равно начинали рандомно падать АОСы Вылечилось основкой всех АОСов и удалением записей из таблицы. Но не ясно, как так получилось, что максимум был достигнут и приводил к таким последствиям? Последний раз редактировалось Lankey; 11.07.2025 в 18:05. | 
|  | 
|  14.07.2025, 12:09 | #6 | 
| Участник | 
			
			Штатное поведение - это как раз создание новых записей, а не использование "свободных". Если сессию перестали использовать, то она должны быть закрыта (удалена запись) и никак иначе Там же дальше в хранимке [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 | 
| Участник | 
			
			Интересно. У нас в этой табличке 65111 записей, но аос не падает. (Правда при остановке может задумываться с сообщениями о закрытии сессии с номером таким то и таких сообщений много. Надо будет перепроверить как идет закрытие сессии) Аксапта 2012 R3 | 
|  | 
|  15.07.2025, 17:37 | #8 | 
| Участник | 
			
			Да. Он просто падает по этому условию, что Вы привели: X++: select @max_val = max(SESSIONID)+1 from SYSCLIENTSESSIONS WITH (UPDLOCK) if (@max_val > 65535) select @sessionid = -3 Может, я не совсем понимаюю, что Вы хотели сказать, Владимир? Я не понимаю, почему он не выбирает неактивные сессиии с меньшими номерами . Подозреваю, что это из-за передаваемого параметра @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 | 
| Участник | 
			
			А у вас там своих кастомизаций нет ? Может они влияют. Я это к тому что у нас тоже дофига записей, почти 65536 но не падает. | 
|  | 
|  15.07.2025, 22:49 | #10 | 
| Участник | Цитата:  1) Если алгоритм хорошо работает, то как у вас дошло до таких высоких номеров? ( у вас же не так много одновременных соединений) . То есть, что к этом привело ? 2) И если дошло до 65111, то что мешает дойти и до 65535 (то есть, столкнуться с "нашей проблемой"). 3) У вас запись с макс номером отдана активной сессий (Status =1)? | 
|  | 
|  16.07.2025, 00:44 | #11 | 
| Участник | 
			
			Где я говорил что алгоритм хорошо работает ? Меня тоже смущает такое множество записей, плюс аос явно тупит при остановке обрабатывая их. Но у нас аос не падает. Вот о чем речь. Посмотрел сейчас рабочую, там максимальный номер 65535 Статус - Неактивный (Status = 0) Тип сеанса - Business connector (clientType = 1) LoginDateTime - 03.04.2023 15:06:58 | 
|  | 
|  16.07.2025, 00:49 | #12 | 
| Участник | 
			
			Из свежих записей (у которых LoginDateTime - 15 июля) - самый большой номер 15886
		 | 
|  | 
|  16.07.2025, 01:03 | #13 | 
| Участник | 
			
			А вот код хранимки Отформатирован тут 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 | 
| Участник | 
			
			Запустил 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 @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 Второй вызов ХП для @maxClientId = 6 тоже отработал, но потом это соединение было разорвано и у соответствующей записи возвращен Status = 0 Хм... Т.е. я был не прав. Это все-таки механизм повторного использования записи. Вопрос только в том, как значение этого параметра определяется. Вероятно, для @licenseType = 1 просто как min()-1 по всей таблице. Для @licenseType = 0 уже как-то сложнее Да, если запустить второй экземпляр Axapta не закрывая первый, то вызов будет с тем же параметром @maxClientId = 2 
				__________________ - Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... Последний раз редактировалось Владимир Максимов; 16.07.2025 в 03:04. | 
|  | 
|  16.07.2025, 13:54 | #15 | 
| Участник | Цитата: Ваш эксперимент был при скольких АОСах и каких типах соединения? У нас несколько AOS и соединения и от обычных юзеров. и батчей и бизнес-коннекторов. Думаю, что от того, какой текущий Clienttype и SessionType , передаваемый @maxClientId может быть разным. Поэтому и эксперимнт должен быть намного сложнее, чтобы это как-то проверить. | 
|  | 
|  16.07.2025, 14:00 | #16 | 
| Участник | |
|  | 
|  16.07.2025, 14:02 | #17 | 
| Участник | |
|  | 
|  17.07.2025, 11:34 | #18 | 
| Участник | 
			
			опечатался похоже Посмотрел еще раз поле 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 | 
|  | 
| 
 |