出處: http://blog.csdn.net/cityhunter172/article/details/727743
今日抽空就說一下 Session 在 .Net v1.0/v1.1 中的存儲模式。大家可在 MSDN 2003 中搜索一下 < sessionState > 即可看到關于 Web.config 中的 < sessionState > 節點元素的描述,共有 Off 、 InProc 、 StateServer 、 SQLServer 四種模式。 Off 、 InProc 分別指“不啟用”、“進程內保存(默認值)”,此兩種模式沒啥講的,所謂 InProc 就是把 Session 保存在 aspnet_wp.exe (Windows 2000 解析 ASP.NET 頁面所用的進程 ) 或 w3wp.exe (Win2003 的進程 ) 中,一旦進程被中止或被重置, Session 將丟失。
一、 引發 Session 丟失的幾種原因
動過手寫代碼的人都知道, Session 丟失是比較常見的事。以下是本人這幾年所遇到的,能夠引發 Session 丟失的原因,不敢說是百分百,丟失概率還是特別高的。錯…,簡直可以說是“相…當…”高哇 ^_^"
1、 存放 Session 的電腦重啟(廢話,若這樣都不丟,你神仙?。?
2、 InProc 模式: aspnet_wp.exe 或 w3wp.exe 在“任務管理器”中或其它情況下導致其進程被終止運行。
3、 InProc 模式:修改 .cs 文件后,編譯了兩次(只編譯一次,有時不會丟失)
4、 InProc 模式:修改了 Web.config
5、 InProc 模式, Windows 2003 環境:應用程序池回收、停止后重啟
6、 InProc 模式:服務器上 bin 目錄里的 .dll 文件被更新
以上列舉的都是 InProc 模式下,容易引發解析 ASP.NET 應用程序重置的原因。是不是覺得很窩火?之前我也有這種感覺,慢慢就習慣啦,再后來就干脆不用這種模式了。于是乎,就有了使用下列兩種模式的嘗試,現寫出來與大家一起分享。
二、 使用 StateServer 保存 Session
StateServer 模式的實質是,把 Session 存放在一個單獨的進程里,此進程獨立于 aspnet_wp.exe 或 w3wp.exe 。啟用此服務后,在“任務管理器”中可以看到一個名為 aspnet_state.exe 的進程,下面開始說明一下設置的具體步驟:
1、 修改注冊表(關鍵步驟,如下圖)
運行 regedit → 打開注冊表 → 找到 HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/aspnet_state/Parameters 節點 → 將 AllowRemoteConnection 的鍵值設置成“ 1 ”( 1 為允許, 0 代表禁止)→ 設置 Port ( 端口號 )
注意事項:
a) 、若 ASP.NET State Service 正在運行,修改注冊表內容后,則需要重新啟動該服務
b) 、注意端口號的鍵值是以十六進制儲存的,可以使用十進制進行修改, 42424 是默認的端口
c) 、 AllowRemoteConnection 的鍵值設置成“ 1 ” 后,意味著允許遠程電腦的連接,也就是說只要知道你的服務端口,就可享用你的 ASP.NET State Service ,即把 Session 存放在你的電腦進程內,因此請大家慎用;鍵值為“ 0 ” 時,僅有 stateConnectionString 為“ tcpip=localhost: 42424 ” 與“ tcpip=127.0.0.1:42424 ” 的情況,方可使用 ASP.NET State Service
2、 開啟 ASP.NET State Service (如下圖)
右鍵點擊“我的電腦”→ 管理 → 服務與應用程序 → 服務 → 雙擊“ ASP.NET State Service ” → 啟動(可設為“自動”)
說明:只要安裝了 .Net Framework v1.0/v1.1 ,都擁有此服務。
3、 更改 Web.config
打開 Web.config → 找到 < sessionState > 節點內容
< sessionState
mode ="InProc"
stateConnectionString ="tcpip=127.0.0.1:42424"
sqlConnectionString ="data source=127.0.0.1;Trusted_Connection=yes"
cookieless ="false"
timeout ="20" />
→ 將其改為以下內容
< sessionState mode ="StateServer" stateConnectionString ="tcpip=192.168.0.2:42424" timeout ="20" />
注意事項:
a) 、設成 StateServer 后,必須要有對應的 stateConnectionString
b) 、注意 IP 地址(可以是遠程計算機 IP 、計算機名稱、域名)與端口號,端口號需與 ASP.NET State Service 的服務端口一致
三、 將 Session 放入 SQLServer 保存
SQLServer 模式就是,把 Session 存放在 SQL Server 數據庫里(注意不是 Oracle ,動動腳趾都能猜到原因啦),下面開始說明一下設置的具體步驟:
1、 啟動相關的數據庫服務(如圖)
運行 SQL Server 服務管理器 → 啟動 SQL Server (最好設為開機自動運行) → 啟動 SQL Server Agent 服務(最好設為開機自動運行)
注意事項:
a) 、注意啟動順序,也可通過下列方式設置: 右鍵點擊“我的電腦”→ 管理 → 服務與應用程序 → 服務 → 找到“ MSSQLSERVER ”與“ SQLSERVERAGENT ” → 啟動并設置啟動類型為“自動”
b) 、 SQL Server Agent 在此處的作用是清除數據庫中已過期的 Session
2、 建立存放 Session 的 DataBase
運行“ SQL 查詢分析器”→ 使用“ sa ”或是擁有“ master ”的 db_owner 權限的用戶登錄數據庫 → 打開查詢文件 C:/WINNT/Microsoft.NET/Framework/v1.1.4322/InstallSqlState.sql (存放在 Windows 系統目錄的 .Net 安裝目錄下可找到) → 直接運行該 sql 腳本 → 刷新數據庫即可看到名為 ASPState 的 DataBase
3、 建立連接數據庫 ASPState 的用戶,并為此用戶授權(此步驟可跳過)
進行此步的原因是:一是不想在 Web.config 中出現 sa 的密碼;二是 tempdb 在數據庫啟動后僅保留 sa 一個帳號的使用權限,其余帳號的權限統統被清除,但保存 Session 又需要用到此 DataBase ;
A) 、運行 SQL Server 的企業管理器 → 展開數據庫的安全性 → 右擊“登錄” → 新建“登錄” → 輸入“名稱” → 選擇 “ SQL Server 身份驗證” → 輸入“密碼” → 指定“數據庫” → 點擊“數據庫訪問” → 勾選 “ ASPState ” → 選中“ db_owner ”角色 → 點擊“確定” → 再一次輸入“密碼” → 點擊“確定” 后即可建立 ASPState 的用戶(此處建立名為“ SessionStateUser ”,密碼為“ 123456 ” 的測試用戶)
B) 、運行 SQL Server 的企業管理器 → 展開“管理” → 展開“ SQL Server 代理” → 右擊“作業” → 點擊“新建作業” → 輸入 “名稱”(此例為 GrantSessionUser ) → 點擊標簽 “步驟” → 新建 → 輸入 “步驟名”(此例為 Grant01 ) → 選擇數據庫“ tempdb ” → 編寫 SQL 腳本“ exec sp_adduser 'SessionStateUser' , 'SessionUser' , 'db_owner' ”→ 確定 → 點擊標簽 “調度” → 新建 → 輸入 “名稱”(此例為 Start01 )→ 選擇類型“ SQL Server 代理啟動時自動啟動” → 確定 → 最后點擊“確定”新增完畢
C )、也可運行以下腳本一次性搞定以上 A 、 B 兩個步驟
/****** 腳本開始 ******/
-- 新建數據庫帳號 SessionStateUser ,默認登錄 ASPState
EXEC sp_addlogin 'SessionStateUser' , '123456' , 'ASPState'
use ASPState -- 切換 DataBase
-- 將 SessionStateUser 授予 db_owner 的權限
exec sp_adduser 'SessionStateUser' , 'SessionUser' , 'db_owner'
use master -- 切換 DataBase
BEGIN TRANSACTION
/****** 聲明變量 ******/
DECLARE @JobID BINARY ( 16 )
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
-- 若沒有,則添加作業的分類
IF ( SELECT COUNT (*) FROM msdb.dbo. syscategories WHERE name = N '[Uncategorized (Local)]' ) < 1
EXECUTE msdb.dbo.sp_add_category @name = N '[Uncategorized (Local)]'
-- 新建作業
EXECUTE @ReturnCode = msdb.dbo.sp_add_job -- 調用存儲過程 sp_add_job
@job_id = @JobID OUTPUT , -- 將返回的 JobID ,賦值給變量
@job_name = N 'GrantSessionUser' , -- 作業名稱
@owner_login_name = NULL, -- 默認為當前用戶所有
@description = null,
@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 -- 出錯則回滾
-- 新建步驟
EXECUTE @ReturnCode = msdb.dbo.sp_add_jobstep -- 調用存儲過程 sp_add_jobstep
@job_id = @JobID , -- 傳入剛剛新建的 JobID
@step_id = 1 ,
@step_name = N 'Grant01' , -- 步驟名稱
@command = N 'exec sp_adduser ''SessionStateUser'', ''SessionUser'' ,''db_owner''',
-- 需要執行的 SQL 腳本(注意用兩個連續的單引號表示 SQL 中的單引號)
@database_name = N 'tempdb' , -- 執行上述 SQL 所用的 DataBase
@server = N '' ,
@database_user_name = N '' ,
@subsystem = N 'TSQL' , -- 執行類型為“ Transact-SQL 腳本”
@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_add_jobschedule
@job_id = @JobID ,
@name = N 'Start01' , -- 調度名稱
@enabled = 1 ,
@freq_type = 64 -- “ 64 ” 表示 當 SQLServerAgent 服務啟動時運行
IF ( @@ERROR <> 0 OR @ReturnCode <> 0 ) GOTO QuitWithRollback
-- 將新建的作業添加到本地數據庫
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 :
/****** 腳本結束 ******/
4、 設置 Web.config 內容
打開 Web.config → 找到 < sessionState > 節點內容 → 修改為以下內容即可:
< sessionState mode ="SQLServer" sqlConnectionString ="data source=192.168.0.2; user id= SessionStateUser; password=123456" timeout ="20" />
注意事項:
a) 、 sqlConnectionString 中不能出現 initial catalog 選項
b) 、 SQL Server Agent 在此處的作用是清除數據庫中已過期的 Session
c )、你若跳過了第三步,則 user id 需要用 sa 進行登錄
d )、若 sqlConnectionString 為 “ data source=127.0.0.1;Trusted_Connection=yes ”,則使用本地計算機 ASPNET ( Windows 2000 系統帳戶)或 Network Service ( Windows 2003 系統帳戶)的身份登錄數據庫。要是數據庫不允許上述用戶登錄,則報錯;同樣,即使上述帳戶能成功登錄,也要分配其 tempdb 的權限,理由是 Session 是保存在 tempdb 中的,若沒有該 DataBase 的存取權限是行不滴。見下圖:
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
