大家好
已有四个多月没写东东啦
今日抽空就说一下 Session 在
Net v
/v
中的存储模式
大家可在 MSDN
中搜索一下 <sessionState> 即可看到关于 nfig 中的<sessionState> 节点元素的描述
共有 Off
InProc
StateServer
SQLServer 四种模式
Off
InProc 分别指
不启用
进程内保存(默认值)
此两种模式没啥讲的
所谓 InProc 就是把 Session 保存在 aspnet_wp
exe (Windows
解析 ASP
NET页面所用的进程) 或 w
wp
exe (Win
的进程) 中
一旦进程被中止或被重置
Session 将丢失
一 引发 Session 丢失的几种原因
动过手写代码的人都知道Session 丢失是比较常见的事以下是本人这几年所遇到的能够引发 Session 丢失的原因不敢说是百分百丢失概率还是特别高的错…简直可以说是相…当…高哇 ^_^
存放 Session 的电脑重启(废话若这样都不丢你神仙啊)
InProc 模式aspnet_wpexe 或 wwpexe 在任务管理器中或其它情况下导致其进程被终止运行
InProc 模式修改 cs 文件后编译了两次(只编译一次有时不会丢失)
InProc 模式修改了 nfig
InProc 模式Windows 环境应用程序池回收停止后重启
InProc 模式服务器上 bin 目录里的 dll 文件被更新
以上列举的都是 InProc 模式下容易引发解析 ASPNET 应用程序重置的原因是不是觉得很窝火?之前我也有这种感觉慢慢就习惯啦再后来就干脆不用这种模式了于是乎就有了使用下列两种模式的尝试现写出来与大家一起分享
二 使用 StateServer 保存 Session
StateServer 模式的实质是把Session 存放在一个单独的进程里此进程独立于 aspnet_wpexe 或 wwpexe 启用此服务后在任务管理器中可以看到一个名为 aspnet_stateexe 的进程下面开始说明一下设置的具体步骤
修改注册表(关键步骤如下图)
运行 regedit → 打开注册表 → 找到HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/aspnet_state/Parameters 节点 → 将 AllowRemoteConnection 的键值设置成( 为允许 代表禁止)→ 设置 Port (端口号)
注意事项
a)若ASPNET State Service 正在运行修改注册表内容后则需要重新启动该服务
b)注意端口号的键值是以十六进制储存的可以使用十进制进行修改 是默认的端口
c)AllowRemoteConnection 的键值设置成后意味着允许远程电脑的连接也就是说只要知道你的服务端口就可享用你的ASPNET State Service即把 Session 存放在你的电脑进程内因此请大家慎用键值为时仅有stateConnectionString 为tcpip=localhost: 与tcpip=:的情况方可使用ASPNET State Service
开启 ASPNET State Service(如下图)
右键点击我的电脑→ 管理 → 服务与应用程序 → 服务 → 双击ASPNET State Service → 启动(可设为自动)
说明只要安装了 Net Framework v/v 都拥有此服务
更改 nfig
打开 nfig → 找到 <sessionState> 节点内容
<sessionState
mode=InProc
stateConnectionString=tcpip=:
sqlConnectionString=data source=;Trusted_Connection=yes
cookieless=false
timeout= />
→ 将其改为以下内容
<sessionState mode=StateServer stateConnectionString=tcpip=: timeout= />
注意事项
a)设成StateServer 后必须要有对应的stateConnectionString
b)注意 IP 地址(可以是远程计算机 IP计算机名称域名)与端口号端口号需与ASPNET State Service 的服务端口一致
三 将 Session 放入 SQLServer 保存
SQLServer 模式就是把Session 存放在 SQL Server 数据库里(注意不是 Oracle 动动脚趾都能猜到原因啦)下面开始说明一下设置的具体步骤
启动相关的数据库服务(如图)
运行SQL Server 服务管理器 → 启动 SQL Server (最好设为开机自动运行) → 启动 SQL Server Agent 服务(最好设为开机自动运行)
注意事项
a)注意启动顺序也可通过下列方式设置 右键点击我的电脑→ 管理 → 服务与应用程序 → 服务 → 找到MSSQLSERVER与SQLSERVERAGENT → 启动并设置启动类型为自动
b)SQL Server Agent在此处的作用是清除数据库中已过期的 Session
建立存放 Session 的 DataBase
运行SQL 查询分析器→ 使用sa或是拥有master的 db_owner 权限的用户登录数据库 → 打开查询文件 C:/WINNT/MicrosoftNET/Framework/v/InstallSqlStatesql (存放在 Windows 系统目录的 Net 安装目录下可找到) → 直接运行该 sql 脚本 → 刷新数据库即可看到名为 ASPState 的 DataBase
建立连接数据库 ASPState 的用户并为此用户授权(此步骤可跳过)
进行此步的原因是一是不想在 nfig 中出现 sa 的密码二是 tempdb 在数据库启动后仅保留 sa 一个帐号的使用权限其余帐号的权限统统被清除但保存 Session又需要用到此 DataBase;
A)运行 SQL Server 的企业管理器 → 展开数据库的安全性 → 右击登录 → 新建登录 → 输入名称 → 选择 SQL Server 身份验证 → 输入密码 → 指定数据库 → 点击数据库访问 → 勾选 ASPState → 选中db_owner角色 → 点击确定 → 再一次输入密码 → 点击确定 后即可建立 ASPState 的用户(此处建立名为SessionStateUser密码为的测试用户)
B)运行 SQL Server 的企业管理器 → 展开管理 → 展开SQL Server 代理 → 右击作业 → 点击新建作业 → 输入 名称(此例为 GrantSessionUser ) → 点击标签 步骤 → 新建 → 输入 步骤名(此例为 Grant) → 选择数据库tempdb → 编写 SQL 脚本execsp_adduser SessionStateUser SessionUser db_owner → 确定 → 点击标签 调度 → 新建 → 输入 名称(此例为 Start )→ 选择类型SQL Server 代理启动时自动启动 → 确定 → 最后点击确定新增完毕
C)也可运行以下脚本一次性搞定以上 AB 两个步骤
/******脚本开始******/
新建数据库帐号 SessionStateUser 默认登录 ASPState
EXEC sp_addlogin SessionStateUser ASPState
use ASPState 切换 DataBase
将 SessionStateUser 授予 db_owner 的权限
exec sp_adduser SessionStateUser SessionUser db_owner
use master 切换 DataBase
BEGIN TRANSACTION
/******声明变量******/
DECLARE @JobID BINARY()
DECLARE @ReturnCode INT
SELECT @ReturnCode =
若没有则添加作业的分类
IF (SELECT COUNT(*) FROM msdbdbosyscategories WHERE name = N[Uncategorized (Local)]) <
EXECUTE msdbdbosp_add_category @name = N[Uncategorized (Local)]
新建作业
EXECUTE @ReturnCode = msdbdbosp_add_job 调用存储过程 sp_add_job
@job_id = @JobID OUTPUT 将返回的 JobID赋值给变量
@job_name = NGrantSessionUser 作业名称
@owner_login_name = NULL 默认为当前用户所有
@description = null
@category_name = N[Uncategorized (Local)] 作业分类归属
@enabled = 是否启用
@notify_level_email =
@notify_level_page =
@notify_level_netsend =
@notify_level_eventlog =
@delete_level=
IF (@@ERROR <> OR @ReturnCode <> ) GOTO QuitWithRollback 出错则回滚
新建步骤
EXECUTE @ReturnCode = msdbdbosp_add_jobstep 调用存储过程 sp_add_jobstep
@job_id = @JobID 传入刚刚新建的 JobID
@step_id =
@step_name = NGrant 步骤名称
@command = Nexec sp_adduser SessionStateUser SessionUser db_owner
需要执行的 SQL 脚本(注意用两个连续的单引号表示 SQL 中的单引号)
@database_name = Ntempdb 执行上述 SQL 所用的 DataBase
@server = N
@database_user_name = N
@subsystem = NTSQL 执行类型为TransactSQL 脚本
@cmdexec_success_code =
@flags =
@retry_attempts =
@retry_interval =
@output_file_name = N
@on_success_step_id =
@on_success_action =
@on_fail_step_id =
@on_fail_action =
IF (@@ERROR <> OR @ReturnCode <> ) GOTO QuitWithRollback
新建调度
EXECUTE @ReturnCode = msdbdbosp_add_jobschedule
@job_id = @JobID
@name = NStart 调度名称
@enabled =
@freq_type = 表示 当 SQLServerAgent 服务启动时运行
IF (@@ERROR <> OR @ReturnCode <> ) GOTO QuitWithRollback
将新建的作业添加到本地数据库
EXECUTE @ReturnCode = msdbdbosp_add_jobserver @job_id = @JobID @server_name = N(local)
IF (@@ERROR <> OR @ReturnCode <> ) GOTO QuitWithRollback
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
IF (@@TRANCOUNT > ) ROLLBACK TRANSACTION
EndSave:
/******脚本结束******/
设置 nfig 内容
打开 nfig → 找到 <sessionState> 节点内容 → 修改为以下内容即可
<sessionState mode=SQLServer sqlConnectionString =data source=; user id= SessionStateUser; password= timeout= />
注意事项
a)sqlConnectionString 中不能出现 initial catalog 选项
b)SQL Server Agent在此处的作用是清除数据库中已过期的 Session
c)你若跳过了第三步则 user id 需要用 sa 进行登录
d)若sqlConnectionString 为 data source=;Trusted_Connection=yes则使用本地计算机ASPNET(Windows 系统帐户)或 Network Service(Windows 系统帐户)的身份登录数据库要是数据库不允许上述用户登录则报错同样即使上述帐户能成功登录也要分配其 tempdb 的权限理由是 Session 是保存在 tempdb 中的若没有该 DataBase 的存取权限是行不滴