使用 Oracle 資料庫儲存 ASP.NET Session State

速記一下使用 Oracle 資料庫儲存 ASP.NET Session State 的方法(我的資料庫是 Oracle 10g)。

首先,到 OTN 網站下載並安裝 Oracle 11g Oracle Data Access Components (ODAC) with Oracle Developer Tools for Visual Studio version 11.2.0.2.1 或更新的版本。(雖然資料庫是 Oracle 10g,但要儲存 ASP.NET session 資料,就必須用 11.x 版的用戶端)

裝好 ODAC with .... 之後,編輯 $HOME$\Network\Admin\tnsnames.ora,把資料來源組態設定好,例如:
TESTDB =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 123.45.67.89)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = MY_ORADB)
    )
  )
這裡的資料來源名稱是 TESTDB。

接著要建立儲存 session state 的資料表和相關物件。這些 SQL 指令就放在 $HOME$\ASP.NET\SQL 目錄下,主要是這兩個檔案:
  1. InstallOracleASPNETCommon.sql (會執行 InstallOracleASPNETCommonSP.plb)
  2. InstallOracleSessionState.sql(會執行 InstallOracleSessionStateSP.plb)
這兩個 SQL 命令檔會將資料物件建立在你目前用來連接資料庫的 user schema 裡面,而且它們都會分別去執行 .plb 的檔案。你可以將 .plb 檔案複製到 C:\ 底下,然後修改 SQL 指令檔的內容。例如,修改 InstallOracleASPNETCommon.sql  時,找到 @@InstallOracleASPNETCommonSP.plb 這行,然後將這行改成 @@C:\InstallOracleASPNETCommonSP.plb。

先執行 InstallOracleASPNETCommon.sql ,然後再執行 InstallOracleSessionState.sql。執行第 二個 SQL 指令檔時,因為其中有用到 create role 命令,而我用來存取資料庫的帳號並無此權限,因此執行 SQL 時會出錯。我自己胡亂修改了一下,try 了幾次,總算成功。如果你也碰到類似問題,可以這麼做:
  1. 用記事本開啟 InstallOracleSessionState.sql。
  2. 假設你希望把資料表建立在 scott 這個帳號,就把字串 "&CurrentUser.." 替換成 "scott."(注意前者有兩個點,後者是一個點)。
  3. 把字串 "ora_aspnet_Sessn_FullAccess" 替換成 "scott"。
  4. 存檔,進入 SQL Plus,以 scott 帳號連接資料庫,依序執行 InstallOracleASPNETCommon.sql 和 InstallOracleSessionState.sql。
  5. 用資料庫工具檢查一下 scott 這個 user schema 裡面有沒有四個名叫 ORA_ASPNET_* 的資料表,有的話應該就 OK 了。
步驟 3 可能不必要,但是做了也無妨,執行 SQL 時會出現一些 grant 權限失敗的訊息而已。如果當中步驟有錯,可執行 UninstallOracleASPNETCommon.sql 和 UninstallOracleSessionState.sql 把相關物件刪除,再重頭來過。

資料庫的部分準備好之後,可以寫個小程式驗證一下。以下是簡易步驟:
  1. 開啟 Visual Studio,New 一個 Web site。
  2. 加入組件參考:
    System.Data.OracleClient.dll
    Oracle.Web.dll
  3. 編輯 Web.config,加入資料庫連線參數:

    <connectionStrings>
    <add name="SessionState" connectionString="User Id=scott;Password=tiger;Data Source=TESTDB"/>
    </connectionStrings>

    還有 sessionState:

    <sessionState mode="Custom" customProvider="MyOracleSessionStateStore" timeout="60">
    <providers>
    <add name="MyOracleSessionStateStore"
    type="Oracle.Web.SessionState.OracleSessionStateStore, Oracle.Web, Version=2.111.6.20, Culture=neutral, PublicKeyToken=89b483f429c47342"
    connectionStringName="SessionState"/>
    </providers>
    </sessionState>

  4. 撰寫 Default.aspx 頁面的 Page_Load 事件:

    protected void Page_Load(object sender, EventArgs e)
    {
    Session["Nothing"] = "Nothing";
    Response.Write("Session ID: " + Session.SessionID + "");
    }

  5. View In Browser。觀察頁面上顯示的 Session ID 數值,然後到資料庫端查看 ORA_ASPNET_SESSIONS 資料表,應該會有一筆對應的 session 記錄。有的話就表示成功了。參考下圖(2011-4-25 增補):

注意事項
  • ORA_ASPNET_SESSIONS 的 SESSIONID 欄位值只有前 24 碼才是 session ID,後面接著的字串看起來有點像 application ID,不是很確定,應可忽略。
  • 注意範例程式碼有一行看似無作用的敘述:

    Session["Nothing"] = "Nothing";

    這是因為如果你沒有 "touch" Session 物件的話,session provider 就不會在資料庫中建立一筆 session 記錄(因此你會看到 ORA_ASPNET_SESSIONAPPLICATIONS 有資料,ORA_ASPNET_SESSIONS 卻沒有)。
  • Oracle 11g ODAC 11.1.0.7.20 附的 SQL 指令會在 Oralce 中建立一個排程,每隔一分鐘會清除無效的 Session 記錄。所謂無效的 Session 記錄,指的是 ORA_ASPNET_SESSIONS 資料表中,EXPIRES(有效期限) 欄位值的時間已經過期的記錄。該欄位的數值就是建立該記錄的時間加上你的網站的 session timeout 的時間,因此你可以透過 Web.config 中的 sessionState 的 timeout 屬性來控制其有效期限。
2011-4-25 補圖:在 Toad 中顯示的刪除無效 Session 記錄的排程:


參考資料

1 則留言:

技術提供:Blogger.
回頂端⬆️