Como configurar o SQL Session State Server para uso com o MSSQL?
Eventualmente você pode ter o interesse de trabalhar com o armazenamento dos valores das variáveis de sessão em uma base de dados.
Em uma plataforma Windows, você pode se utilizar do Asp.Net State Service para este recurso, porém, por padrão ele não é habilitado na plataforma, deste modo é necessário que você execute o procedimento descrito mais abaixo.
1 – Gere um script padrão rodando um executável chamado aspnet_regsql.exe . Ele se encontra-se localmente em: C:\WindowsMicrosoft\.NETFramework\v2.0.50727
Informe os parâmetros:
-d [databaseName]
-sstype c
-sqlexportonly [filename]
-ssadd
Por exemplo, se o nome do seu banco de dados é minha_base , você pode rodar aspnet_regsql com esta linha de comando:
Aspnet_regsql -d minha_base -sstype c -sqlexportonly c:meu_script.sql –ssadd
Este comando irá gerar um arquivo chamado meu_script.sql que, no exemplo, foi direcionado para a raiz do drive C .
2 - Em seguida, execute o Enterprise Manager ou SQL Server Management Studio Express e carregue o arquivo “meu_script.sql”.
OBS: Estas instruções assumem que você possua conhecimentos sobre o Enterprise Manager ou SQL Server Management Studio.
3 – Edite o Script, localize e remova as linhas abaixo, elas tentam criar uma base de dados. Supondo que você já possui uma base MSSQL:
USE master
GO
/* Create and populate the session state database */
IF DB_ID(N'minha_base') IS NULL BEGIN
DECLARE @cmd nvarchar(500)
SET @cmd = N'CREATE DATABASE [minha_base]'
EXEC(@cmd)
END
4 - É necessário também deletar as linhas para remover o job, se existir.
DECLARE @jobname nvarchar(200)
SET @jobname = N'minha_base' '_Job_DeleteExpiredSessions'
-- Delete the [local] job
-- We expected to get an error if the job doesn't exist.
PRINT 'If the job does not exist, an error from msdb.dbo.sp_delete_job is expected.'
EXECUTE msdb.dbo.sp_delete_job @job_name = @jobname
GO
DECLARE @sstype nvarchar(128)
SET @sstype = N'sstype_custom'
IF UPPER(@sstype) = 'SSTYPE_TEMP' AND OBJECT_ID(N'dbo.ASPState_Startup', 'P') IS NOT NULL BEGIN
DROP PROCEDURE dbo.ASPState_Startup
END
USE [minha_base]
GO
IF OBJECT_ID(N'dbo.ASPStateTempSessions','U') IS NOT NULL BEGIN
DROP TABLE dbo.ASPStateTempSessions
END
IF OBJECT_ID(N'dbo.ASPStateTempApplications','U') IS NOT NULL BEGIN
DROP TABLE dbo.ASPStateTempApplications
END
5 - Como próximo passo, se faz necessário deletar o script que cria o job para apagar as sessões expiradas. O código é semelhante ao abaixo:
BEGIN TRANSACTION
DECLARE @JobID BINARY(16)
DECLARE @ReturnCode int
DECLARE @nameT nchar(200)
SELECT @ReturnCode = 0
-- Add the job
SET @nameT = N'minha_base' '_Job_DeleteExpiredSessions'
EXECUTE @ReturnCode = msdb.dbo.sp_add_job
@job_id = @JobID OUTPUT,
@job_name = @nameT,
@owner_login_name = NULL,
@description = N'Deletes expired sessions from the session state database.',
@category_name = N'[Uncategorized (Local)]',
@enabled = 1,
@notify_level_email = 0,
@notify_level_page = 0,
@notify_level_netsend = 0,
@notify_level_eventlog = 0,
@delete_level= 0
IF (@@ERROR 0 OR @ReturnCode 0) GOTO QuitWithRollback
-- Add the job steps
SET @nameT = N'minha_base' '_JobStep_DeleteExpiredSessions'
EXECUTE @ReturnCode = msdb.dbo.sp_add_jobstep
@job_id = @JobID,
@step_id = 1,
@step_name = @nameT,
@command = N'EXECUTE DeleteExpiredSessions',
@database_name = N'minha_base',
@server = N'',
@subsystem = N'TSQL',
@cmdexec_success_code = 0,
@flags = 0,
@retry_attempts = 0,
@retry_interval = 1,
@output_file_name = N'',
@on_success_step_id = 0,
@on_success_action = 1,
@on_fail_step_id = 0,
@on_fail_action = 2
IF (@@ERROR 0 OR @ReturnCode 0) GOTO QuitWithRollback
EXECUTE @ReturnCode = msdb.dbo.sp_update_job @job_id = @JobID, @start_step_id = 1
IF (@@ERROR 0 OR @ReturnCode 0) GOTO QuitWithRollback
-- Add the job schedules
SET @nameT = N'minha_base' '_JobSchedule_DeleteExpiredSessions'
EXECUTE @ReturnCode = msdb.dbo.sp_add_jobschedule
@job_id = @JobID,
@name = @nameT,
@enabled = 1,
@freq_type = 4,
@active_start_date = 20001016,
@active_start_time = 0,
@freq_interval = 1,
@freq_subday_type = 4,
@freq_subday_interval = 1,
@freq_relative_interval = 0,
@freq_recurrence_factor = 0,
@active_end_date = 99991231,
@active_end_time = 235959
IF (@@ERROR 0 OR @ReturnCode 0) GOTO QuitWithRollback
-- Add the Target Servers
EXECUTE @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @JobID, @server_name = N'(local)'
IF (@@ERROR 0 OR @ReturnCode 0) GOTO QuitWithRollback
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:
GO
6 - A última etapa de edição é restituir uma maneira de excluir as variáveis de sessão expiradas.
Então faça uma busca pelo nome da stored procedure TempGetAppID e insira a linha abaixo no topo da execução:
EXECUTE DeleteExpiredSessions
O resultado do script será:
DECLARE @cmd nchar(4000)
SET @cmd = N'
CREATE PROCEDURE dbo.TempGetAppID
@appName tAppName,
@appId int OUTPUT
AS
Exec [dbo].[DeleteExpiredSessions]
SET @appName = LOWER(@appName)
SET @appId = NULL
SELECT @appId = AppId
FROM [minha_base].dbo.ASPStateTempApplications
WHERE AppName = @appName
IF @appId IS NULL BEGIN
BEGIN TRAN
SELECT @appId = AppId
FROM [minha_base].dbo.ASPStateTempApplications WITH (TABLOCKX)
WHERE AppName = @appName
IF @appId IS NULL
BEGIN
EXEC GetHashCode @appName, @appId OUTPUT
INSERT [minha_base].dbo.ASPStateTempApplications
VALUES
(@appId, @appName)
IF @@ERROR = 2627
BEGIN
DECLARE @dupApp tAppName
SELECT @dupApp = RTRIM(AppName)
FROM [minha_base].dbo.ASPStateTempApplications
WHERE AppId = @appId
RAISERROR(''SQL session state fatal error: hash-code collision between applications ''''%s'''' and ''''%s''''. Please rename the 1st application to resolve the problem.'',
18, 1, @appName, @dupApp)
END
END
COMMIT
END
RETURN 0'
EXEC(@cmd)
GO
Esse processo deve apagar todos dos dados das sessões expiradas.
Normalmente, esta modificação funciona para a maior parte das instalações.
Caso você possua uma quantidade grande de tráfego, pode ser necessário otimizar a procedure DeleteExpiredSessions.
Existem muitas modificações disponíveis na web pesquisando sobre DeleteExpiredSession juntamente com a palavra asp.net.
7 - Em seguida, você deve alterar as configurações do seu arquivo web.config conforme o exemplo abaixo:
mode="SQLServer"
allowCustomSqlDatabase="true"
sqlConnectionString="Server=nome_do_servidor; Database=minha_base; uid=login; pwd=senha;"
cookieless="false"
timeout="20"
/>
Substitua os campos nome_do_servidor, Database, uid e pwd pelos dados da base que você possui.