چگونه می توان از SQL Session استفاده نمود؟

 

نحوه استفاده از SQL Session

 

به طور کلی در ASP.net  سه نوع session  وجود دارد که به شرح ذیل می باشند :

 

الف - Inprocess Session : عملکرد این نوع بالاتر بوده و در تنظیمات ASP.Net به صورت پیش فرض از این نوع session استفاده می شود

 

ب -  OutProcess Session (State Server) : این نوع به نام State Server نیز شناخته می شود. این session  از سرویس ویندوز ASP State جهت تنظیمات استفاده می نماید لذا برای استفاده از آن باید این سرویس ویندوز را در وب سرور اجرا نمایید.
لازم به ذکر است که ایران هاست به دلیل استفاده نمودن از قابلیت
Isolated Application pool ، از این نوع session  در پلانهای اشتراکی خود پشتیبانی نمی نماید.

 

پ- SQL Session(SQL Server Mode) : این نوع sessionها در دیتابیس ذخیره می شوند و با ریست شدن Application pool هاست، مشکلی برایsession ها به وجود نخواهد آمد.(session ها expire نمی شوند) بنابراین از این نوعsession  برای سایت هایی که دارای sessionهای سنگین می باشند استفاده می گردد.

برای آگاهی از نحوه استفاده از  session نوع «پ» در پلانهای اشتراکی ایران هاست می توانید یکی از راهکارهای ذیل را دنبال نمایید :

راهکار اول:

دلایل مختلفی برای setupنمودن SQL Session Server وجود دارد:

  1. در سروهای اشتراکی اغلب پردازش های ASP.NET پاکسازی شده و از دست می رود. این موضوع باعث می شود تا متغیرهای session   و احنمالا خود session منقضی شود.(بسته شود (.
  2. دلیل دیگر برای  راه اندازی Session Server مصرف حافظه (Memory) می باشد که با استفاده از Session Server شما حافظه را برای اجرای برنامه آزاد خواهید کرد .

متاسفانه اسکریپت پیش فرض که Microsoft ارائه می دهد نیاز به نصب SQL Job  دارد و اکثر شرکت های هاستینگ اجازه آن را به کاربر نمی دهد.

برای حل این موضوع اولین مرحله  ایجاد یک اسکریپت پیش فرض می باشد. شما می توانید این کار را با اجرا نمودن دستور ذیل در شاخه C:\Windows\Microsoft.NET\Framework\v4.0.30319 با پارامترهای: 

-d [databaseName]
-sstype c
-sqlexportonly [filename]
-ssadd

 

در Command Prompt اجرا نمایید. به طور مثال اگر اسم دیتابیس شما  SampleDatabaseباشد بایدaspnet_regsql  را مانند نمونه، اینگونه از Command Prompt  اجرا کنید:

 

 

Aspnet_regsql -d SampleDatabase -sstype c -sqlexportonly 


c:\sqlstate.sql –ssadd

 

 

که این دستور یک SQL  Script برای ساختن tableهای SQL Session و ذخیره کردن پروسس ها در دیتابیس شما با نام Sample Database در ریشه درایو  C در فایلی به نام sqlstate.sql می سازد.
بعد از این مرحله با استفاده از SQL Enterprise Manager و یا SQL Server Management Studio Express اسکریپت ایجاد شده را لود نمایید.
در قسمت  server name آی پی  SQL سرور را وارد نموده و با  نام کاربری و کلمه عبور  مربوط به دیتابیس خود وارد نرم افزار شوید.

 

 

 

 

 

 

می توانید نسخه رایگان SQL Server Management Studio Express را از لینک زیر دریافت نمایید:

 

http://www.microsoft.com/download/en/details.aspx?displaylang=en &id=8961

شما باید خطهای زیر را که تقریبا در خط 34 وجود دارد از اسکریپت حذف نمایید:

 

 

USE master

 

GO

/* Create and populate the session state database */

IF DB_ID(N'username_dotnetnuke') IS NULL BEGIN

 

    DECLARE @cmd nvarchar(500)

 

    SET @cmd = N'CREATE DATABASE [username_dotnetnuke]'

    EXEC(@cmd)

END 

همچنین خط هایی بلافاصله بعد از خط های حذف شده وجود دارد که باید آنها را حذف نمایید. برای انجام اینکار دومین کلمه use که در جستجو پیدا می کنید را به همراه تمام خط هایی که تحت نام دیتابیس شما آمده اند را پاک کنید.

 

 

DECLARE @jobname nvarchar(200)
SET @jobname = N'username_dotnetnuke' '_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 [username_dotnetnuke]
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

 

قدم بعدی حذف اسکریپتی  است که Jobهایی را برای پاک کردن expired session ها می سازد. (می توانید آن را در قسمت پایینی اسکریپت پیدا کنید) کدی که باید حذف شود شبیه کد زیر است:

 

 

BEGIN TRANSACTION            
    DECLARE @JobID BINARY(16)  
    DECLARE @ReturnCode int    
    DECLARE @nameT nchar(200)
    SELECT @ReturnCode = 0     

    -- Add the job
    SET @nameT = N'username_dotnetnuke' '_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'username_dotnetnuke' '_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'username_dotnetnuke', 
            @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'username_dotnetnuke' '_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

 

آخرین مرحله اجرای راهکاری است که متغییرهای Expired session ها را حذف نماید.

Job ی که حذف نموده اید این کار را انجام می داد اما وقتی این Job وجود ندارد به راهکار دیگری احتیاج داریم، بنابراین جستجویی برای یک Stored Procedure به نام TempGetAppID انجام دهید و خط پایین را در اولین خط اجرایی قرار دهید:

 

 

EXECUTE DeleteExpiredSessions

 

نتیجه، اسکریپتی شبیه به این خواهد بود:

 

 

DECLARE @cmd nchar(4000)

SET @cmd = N'
    CREATE PROCEDURE dbo.TempGetAppID
    @appName    tAppName,
    @appId      int OUTPUT
    AS
    
EXECUTE DeleteExpiredSessions
    SET @appName = LOWER(@appName)
    SET @appId = NULL

    SELECT @appId = AppId
    FROM [username_dotnetnuke].dbo.ASPStateTempApplications
    WHERE AppName = @appName

    IF @appId IS NULL BEGIN
        BEGIN TRAN        

        SELECT @appId = AppId
        FROM [username_dotnetnuke].dbo.ASPStateTempApplications WITH (TABLOCKX)
        WHERE AppName = @appName
        
        IF @appId IS NULL
        BEGIN
            EXEC GetHashCode @appName, @appId OUTPUT
            
            INSERT [username_dotnetnuke].dbo.ASPStateTempApplications
            VALUES
            (@appId, @appName)
            
            IF @@ERROR = 2627 
            BEGIN
                DECLARE @dupApp tAppName
            
                SELECT @dupApp = RTRIM(AppName)
                FROM [username_dotnetnuke].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

 

این کار Expired Session ها را هر زمانی که Session Data درخواست می شود حذف می نماید.

 

 بعداز اضافه شدن جداول (مورد نیاز در دیتابیس مربوطه) با دستور بالا، باید در فایل web.config خود تغییرات لازم برای ست نمودن Sessionها در دیتابیس را اعمال نمایید.

 

 در زیر نمونه ای از این کد را مشاهده می نمایید :

 


 

<sessionState mode="SQLServer"
      allowCustomSqlDatabase="true"
sqlConnectionString="Server=yourServer; Database=yourDatabase; uid=userName_xyz; pwd=Abc123;"
      cookieless="false" 
      timeout="20" 
    />

لازم به ذکر است که انجام این تنظیمات و یا اعمال و استفاده از راه حل های دیگر کاملاً به عهده خود شما بوده و ایران هاست در این زمینه و یا ارائه راهکار های دیگر پشتیبانی نخواهد داشت.( این توضیحات نیز تنها جهت راهنمایی شما ارائه شده است)

 

 

راهکار دوم:

 

دلایل مختلفی برای setup نمودن SQL Session Server وجود دارد:

 

  1. در سروهای اشتراکی اغلب پردازش های ASP.NET پاکسازی شده و از دست می رود. این موضوع باعث می شود تا متغیرهای session  و احنمالا خود session منقضی شود.(بسته شود (.
  2. دلیل دیگر برای  راه اندازی Session Server مصرف حافظه (Memory) می باشد که با استفاده از Session Server شما حافظه را برای اجرای برنامه آزاد خواهید کرد .

 

متاسفانه اسکریپت پیش فرض که Microsoftارائه می دهد نیاز به نصب SQL Job  دارد و اکثر شرکت های هاستینگ اجازه آن را به کاربر نمی دهند .

برای حل این موضوع اولین مرحله  ایجاد یک دیتابیس می باشد. ابتدا در سیستم لوکال خود از طریق نرم افزار SQL Enterprise Manager و یا SQL Server Management Studio Express یک دیتابیس به همراه نام کاربری و کلمه عبور دلخواه ایجاد نمایید.

سپس دستور ذیل را در شاخه C:\Windows\Microsoft.NET\Framework\v4.0.30319 در Command Prompt اجرا نمایید. به طور مثال اگر اسم دیتابیس شما dbtest باشد باید aspnet_regsql  را مانند نمونه، اینگونه از Command Prompt اجرا کنید:

 

 

aspnet_regsql -S localhost –U sa -P (dbpassword) –d  (db name) -ssadd -sstype c

 

 

با اجرای این دستور tableهای مورد نیاز برای SQL Session و ذخیره کردن processها در دیتابیس شما ساخته می شود.

می توانید نسخه رایگان SQL Server Management Studio Express را از لینک زیر دریافت نمایید:

http://www.microsoft.com/download/en/details.aspx?displaylang=en &id=8961

آخرین مرحله اضافه نمودن خط زیر در store procedure به نام  dbo.TempGetAppID می باشد.
برای انجام اینکار از طریق نرم افزار
management studio به دیتابیس لوکال خود وصل شده و جستجویی برای یافتن Stored Procedure با نام dbo.TempGetAppID انجام دهید. سپس آن را انتخاب کرده و روی Edit query کلیک نمایید و خط پایین را در اولین خط اجرایی آن قرار دهید:

 

 

 

EXECUTE DeleteExpiredSessions

 

نتیجه به صورت زیر خواهد بود:

 

DECLARE @cmd nchar(4000)

SET @cmd = N'
    CREATE PROCEDURE dbo.TempGetAppID
    @appName    tAppName,
    @appId      int OUTPUT
    AS
    
EXECUTE DeleteExpiredSessions
    SET @appName = LOWER(@appName)
    SET @appId = NULL

    SELECT @appId = AppId
    FROM [username_dotnetnuke].dbo.ASPStateTempApplications
    WHERE AppName = @appName

    IF @appId IS NULL BEGIN
        BEGIN TRAN        

        SELECT @appId = AppId
        FROM [username_dotnetnuke].dbo.ASPStateTempApplications WITH (TABLOCKX)
        WHERE AppName = @appName
        
        IF @appId IS NULL
        BEGIN
            EXEC GetHashCode @appName, @appId OUTPUT
            
            INSERT [username_dotnetnuke].dbo.ASPStateTempApplications
            VALUES
            (@appId, @appName)
            
            IF @@ERROR = 2627 
            BEGIN
                DECLARE @dupApp tAppName
            
                SELECT @dupApp = RTRIM(AppName)
                FROM [username_dotnetnuke].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

 

 

این کار Expired Session ها را هر زمانی که Session Data درخواست می شود حذف می نماید.

حال می توانید دیگر جداول مورد نیاز دیتابیس خود را ایجاد نموده و آن را تکمیل نمایید. بعد از کامل نمودن دیتابیس خود، می توانید از آن یک Full Backup تهیه نموده و سپس backup مربوطه را روی دیتابیس هاست خود restore نمایید.
برای آگاهی از نحوه تهیه بک آپ و ریستور روی هاست خود، به لینک ذیل مراجعه فرمایید:

 

http://www.iranhost.com/Webguide/Default.aspx?Article=176

برای استفاده از حالت SQL session باید در فایل web.config خود نیز تغییرات لازمه را اعمال نمایید.

در زیر نمونه ای از این کد را مشاهده می نمایید :

 

<sessionState mode="SQLServer"
      allowCustomSqlDatabase="true"
sqlConnectionString="Server=yourServer; Database=yourDatabase; uid=userName_xyz; pwd=Abc123;"
      cookieless="false" 
      timeout="20" 
    />

 

لازم به ذکر است که انجام این تنظیمات و یا اعمال و استفاده از راه حل های دیگر کاملاً به عهده خود شما بوده و ایران هاست در این زمینه و یا ارائه راهکار های دیگر، پشتیبانی نخواهد داشت. (این توضیحات نیز تنها جهت راهنمایی شما ارائه شده است.)