大家好
已有四個多月沒寫東東啦
今日抽空就說一下 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_wp
exe 或 w
wp
exe 在
任務管理器
中或其它情況下導致其進程被終止運行
InProc 模式
修改
cs 文件後
編譯了兩次(只編譯一次
有時不會丟失)
InProc 模式
修改了 nfig
InProc 模式
Windows
環境
應用程序池回收
停止後重啟
InProc 模式
服務器上 bin 目錄裡的
dll 文件被更新
以上列舉的都是 InProc 模式下
容易引發解析 ASP
NET 應用程序重置的原因
是不是覺得很窩火?之前我也有這種感覺
慢慢就習慣啦
再後來就干脆不用這種模式了
於是乎
就有了使用下列兩種模式的嘗試
現寫出來與大家一起分享
二 使用 StateServer 保存 Session
StateServer 模式的實質是
把Session 存放在一個單獨的進程裡
此進程獨立於 aspnet_wp
exe 或 w
wp
exe
啟用此服務後
在
任務管理器
中可以看到一個名為 aspnet_state
exe 的進程
下面開始說明一下設置的具體步驟
修改注冊表(關鍵步驟
如下圖)
運行 regedit → 打開注冊表 → 找到HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/aspnet_state/Parameters 節點 → 將 AllowRemoteConnection 的鍵值設置成
(
為允許
代表禁止)→ 設置 Port (端口號)
注意事項
a)
若ASP
NET State Service 正在運行
修改注冊表內容後
則需要重新啟動該服務
b)
注意端口號的鍵值是以十六進制儲存的
可以使用十進制進行修改
是默認的端口
c)
AllowRemoteConnection 的鍵值設置成
後
意味著允許遠程電腦的連接
也就是說只要知道你的服務端口
就可享用你的ASP
NET State Service
即把 Session 存放在你的電腦進程內
因此請大家慎用
鍵值為
時
僅有stateConnectionString 為
tcpip=localhost:
與
tcpip=
:
的情況
方可使用ASP
NET State Service
開啟 ASP
NET State Service(如下圖)
右鍵點擊
我的電腦
→ 管理 → 服務與應用程序 → 服務 → 雙擊
ASP
NET 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
計算機名稱
域名)與端口號
端口號需與ASP
NET 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/Microsoft
NET/Framework/v
/InstallSqlState
sql (存放在 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)
也可運行以下腳本一次性搞定以上 A
B 兩個步驟
/******腳本開始******/
新建數據庫帳號 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 msdb
dbo
syscategories WHERE name = N
[Uncategorized (Local)]
) <
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 =
是否啟用
@notify_level_email =
@notify_level_page =
@notify_level_netsend =
@notify_level_eventlog =
@delete_level=
IF (@@ERROR <>
OR @ReturnCode <>
) GOTO QuitWithRollback
出錯則回滾
新建步驟
EXECUTE @ReturnCode = msdb
dbo
sp_add_jobstep
調用存儲過程 sp_add_jobstep
@job_id = @JobID
傳入剛剛新建的 JobID
@step_id =
@step_name = N
Grant
步驟名稱
@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 =
@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 = msdb
dbo
sp_add_jobschedule
@job_id = @JobID
@name = N
Start
調度名稱
@enabled =
@freq_type =
表示 當 SQLServerAgent 服務啟動時運行
IF (@@ERROR <>
OR @ReturnCode <>
) GOTO QuitWithRollback
將新建的作業添加到本地數據庫
EXECUTE @ReturnCode = msdb
dbo
sp_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 的存取權限是行不滴
From:http://tw.wingwit.com/Article/program/net/201311/13850.html