چگونه می توان از 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 نمایید.
 


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

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

 

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

 

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