SQL会话状态-数据库SessionId与ASP.NET_SessionID值不同

胆碱

我正在使用SQL Server 2008为.NET4应用程序存储会话。会话将存储在[DatabaseA]中。对此没有任何其他自定义配置,因此ASPState数据库完全是开箱即用的方式(使用aspnet_regsql)

我的主应用程序在[DatabaseB](同一服务器)上运行。在此数据库中,我有2个表,这些表记录了一些数据以及sessionID。

当通过SQL代理运行[DeleteExpiredSessions]存储过程(在DatabaseA上)时,正确地从ASPState中删除了会话,但是我想扩展它以从[DatabaseB]中删除基于SessionID的行。

我尝试编辑[DeleteExpiredSessions]存储过程以包括以下SQL

    OPEN ExpiredSessionCursor

    FETCH NEXT FROM ExpiredSessionCursor INTO @SessionID

    WHILE @@FETCH_STATUS = 0 
        BEGIN
            -- BEGIN MY ADDITIONS
            DECLARE @myRecordCount int
            SELECT @myRecordCount= COUNT(*) FROM [DatabaseB].dbo.Table1 WHERE [DatabaseB].dbo.Table1.SessionId = @SessionID -- AND [DatabaseB].dbo.Table1.DateEntered < @now
            SELECT @myRecordCount 
            DELETE FROM [DatabaseB].dbo.Table1 WHERE [DatabaseB].dbo.Table1.SessionId = @SessionID AND [DatabaseB].dbo.Table1.DateEntered < @now
            DELETE FROM [DatabaseB].dbo.Table2 WHERE [DatabaseB].dbo.Table2.SessionId = @SessionID AND [DatabaseB].dbo.Table2.DateEntered < @now
            -- END MY ADDITIONS

            DELETE FROM [DatabaseA].dbo.ASPStateTempSessions WHERE SessionID = @SessionID AND Expires < @now
            FETCH NEXT FROM ExpiredSessionCursor INTO @SessionID
        END

    CLOSE ExpiredSessionCursor

    DEALLOCATE ExpiredSessionCursor

但是@myRecordCount返回0行。没有报告错误(代理作业正确运行,并且在SQL Profiler中没有任何错误),并且@myRecordCount在这种情况下应该返回4。

DECLARE / SELECT COUNT作为调试器存在。

更新

因此调试了sql后发现:

SELECT SessionId
        FROM [ASPState].dbo.ASPStateTempSessions WITH (READUNCOMMITTED)
        WHERE Expires < GETUTCDATE() 
--Returns SessionId = '3wj5nyrlz02ezw1vvjts4gjv28d8c075'

SELECT * FROM [DatabaseB].dbo.Table1 -- returns (4) results
SELECT * FROM [DatabaseB].dbo.Table1 WHERE [DatabaseB].dbo.Table1.SessionId = '3wj5nyrlz02ezw1vvjts4gjv28d8c075' -- returns (0) results

我推断出SessionId是错误的。存储的[DatabaseB].dbo.Table1是'3wj5nyrlz02ezw1vvjts4gjv'-注意字符串的截断

现在,我的.NET代码(使用EF6.1.3)用于存储会话变量,Table1.SessionId = HttpContext.Current.Session.SessionID这意味着3wj5nyrlz02ezw1vvjts4gjv正在存储该代码。CookieASP.NET_SessionId也具有相同的值。

Table1的SessionId列的长度与ASPState tmpSession表的长度相同(88)

更新的问题有趣的是,ASPStateTempSessions.SessionId变量似乎附加
28d8c075在其末尾。因此,ASP.NET_SessionId和HttpContext.Current.Session.SessionID是,3wj5nyrlz02ezw1vvjts4gjv而ASPStateTempSessions.SessionId是3wj5nyrlz02ezw1vvjts4gjv28d8c075

我刚刚清除了所有会话变量和cookie,并且有了一个新的会话变量,但是28d8c075仍被删除/附加到各种cookie和数据值中。

我了解这是因为ASPStateTempSessions将应用程序哈希的后缀附加到SessionId(https://msdn.microsoft.com/zh-cn/library/aa478952.aspx

Column Name Column Type Description
SessionId   nvarchar(88)    Session ID + application ID

如何将其返回到HttpContext.Current.Session.SessionID而不是SessionId?

胆碱

解决了

问题(正如我最初诊断的那样)是应用程序ID没有传递给SessionID变量。因此,我执行了以下步骤:

1)在Web.Config中创建了一个后备变量(AppName不太可能更改)

<add key="AppId" value="685293685"/>

为什么?-这是从ASPState [TempGetAppID]返回的appName的ID

2)[GetApplicationIdForSession]在DatabaseB中创建一个存储过程

DECLARE @appId int

    EXEC    [ASPState].dbo.[TempGetAppID]
        @appName = @iisName,
        @appId = @appId OUTPUT

    SELECT  @appId as N'AppId'

为什么?-这利用了将AppName哈希到正确的AppId的内置SQL State SP来保持一致性。(即我不是在编写单独的.net函数来尝试获得与SQL相同的值)

3)在Global.asax.vb中

Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
        Using db As New SqlConnection(ConfigurationManager.ConnectionStrings("LocalServer").ConnectionString)
            db.Open()
            Using cmd As SqlCommand = db.CreateCommand()
                cmd.CommandText = "GetApplicationIdForSession"
                cmd.CommandType = CommandType.StoredProcedure
                cmd.Parameters.AddWithValue("iisName", HttpRuntime.AppDomainAppId.ToLower)
                Using dr As SqlDataReader = cmd.ExecuteReader()
                    If dr IsNot Nothing AndAlso dr.Read() Then
                        Application("AppId") = CType(dr("appId"), Integer)
                    Else
                        Application("AppId") = CType(ConfigurationManager.AppSettings("AppId"), Integer)
                    End If
                End Using
            End Using
            db.Close()
        End Using
        ' Fires when the application is started
    End Sub

为什么?-HttpRuntime.AppDomainAppId与ASPState数据库(DatabaseA)中使用的值相同。因此我将其传递给在步骤2中创建的存储过程,然后将输出存储在应用程序变量中,这样我就不必每次都访问数据库来获取sessionid。

4)在我的页面继承自的基类中创建此函数

Public Function GetAppIdHash() As String

        Dim hashCode As Integer = CType(Application("AppId"), Integer)
        Return ((hashCode).ToString("X2")).ToLower

    End Function

为什么?-这将获取应用程序变量(“ AppId”)并返回十六进制输出

5)将存储会话ID变量的.net代码从:Table1.SessionId = HttpContext.Current.Session.SessionID更改为Table1.SessionId = HttpContext.Current.Session.SessionID & GetAppIdHash()

6)DeleteExpiredSessionsSP被更新为此处列出的-happy中期版本- http://sqlperformance.com/2013/01/t-sql-queries/optimize-aspstate和附加SQL命令被附加到它。

ALTER PROCEDURE [dbo].[DeleteExpiredSessions]
  @top INT = 1000
AS
BEGIN
  SET NOCOUNT ON;

  DECLARE @now DATETIME, @c INT;
  SELECT @now = GETUTCDATE(), @c = 1;

 /* START Additional SQL */
    CREATE TABLE #tblExpiredSessions 
    ( 
        SessionId nvarchar(88) NOT NULL PRIMARY KEY
    )
    INSERT #tblExpiredSessions (SessionId)
        SELECT SessionId
        FROM [ASPState].dbo.ASPStateTempSessions WITH (READUNCOMMITTED)
        WHERE Expires < @now
    /* END Additional SQL */

  BEGIN TRANSACTION;

  WHILE @c <> 0
  BEGIN
    ;WITH x AS 
    (
      SELECT TOP (@top) SessionId
        FROM [ASPState].dbo.ASPStateTempSessions
        WHERE Expires < @now
        ORDER BY SessionId
    )
    DELETE x;

    SET @c = @@ROWCOUNT;

    IF @@TRANCOUNT = 1
    BEGIN
      COMMIT TRANSACTION;
      BEGIN TRANSACTION;
    END
  END

  IF @@TRANCOUNT = 1
  BEGIN
    COMMIT TRANSACTION;
  END

  /* START Additional SQL */
  DELETE FROM DatabaseB.dbo.Table1 WHERE DatabaseB.dbo.Table2.SessionId in (SELECT * FROM #tblExpiredSessions)
  DELETE FROM DatabaseB.dbo.Table2 WHERE DatabaseB.dbo.Table2.SessionId in (SELECT * FROM #tblExpiredSessions)

  DROP TABLE #tblExpiredSessions
  /* END Additional SQL */
END

旁注-我不是SQL向导,因此如果有人可以提出对DELETE FROM DatabaseB.dbo.Table1etc部分的改进建议,将不胜感激。(例如查询中的位置,它是否可以与CTE一起使用),对我来说目前似乎有些笨拙。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

ASP.Net SQL Server 会话状态与持久会话状态

来自分类Dev

是否可以共享 SQL Server 数据库以在 Asp.Net Web Forms 中存储会话状态

来自分类Dev

ASP.NET在应用程序数据库中存储会话状态

来自分类Dev

在AWS RDS上使用ASP会话状态数据库

来自分类Dev

在AWS RDS上使用ASP会话状态数据库

来自分类Dev

从数据库返回某些值的安全方法(SQL SERVER和ASP.NET)

来自分类Dev

发布后将asp.net mvc 4本地数据库转换为sql数据库

来自分类Dev

ASP.NET_SessionId超时时未生成其他会话

来自分类Dev

在 sql 命令中使用时,会话值未从数据库获取任何数据

来自分类Dev

使用ASP.NET将Excel数据导入到SQL数据库

来自分类Dev

从ASP.net SQL数据库检索数据到amchart

来自分类Dev

从文本框asp.net C#将数据保存到sql数据库

来自分类Dev

ASP.NET注册页:无法在sql数据库中插入数据

来自分类Dev

ASP.NET MVC会话状态超时

来自分类Dev

不断丢失会话状态ASP.NET

来自分类Dev

ASP NET MVC 5会话状态

来自分类Dev

.net检查数据集是否与sql数据库不同

来自分类Dev

.NET数据库连接状态

来自分类Dev

如何从Asp.Net中的SQL数据库引用SQL路径的jQuery SlideShow

来自分类Dev

将ASP.NET身份存储移动到EF Sql数据库

来自分类Dev

如何从ASP.NET API使用SQL Azure数据库?

来自分类Dev

在asp.net中访问sql数据库的有效方法是什么

来自分类Dev

使用WebForms的ASP.Net Identity到现有SQL数据库

来自分类Dev

无法从ASP.NET中的SQL数据库准确获取值

来自分类Dev

如何将ASP.NET MVC数据库从LocalDb传输到SQL Server?

来自分类Dev

具有SQL Server数据库连接功能的ASP.Net Web服务

来自分类Dev

使用SQL Server CE数据库慢速查询的C#/ ASP.NET网站

来自分类Dev

将图像插入ASP.NET中的本地SQL Server数据库

来自分类Dev

通过asp.net从多个网页访问SQL Server数据库

Related 相关文章

  1. 1

    ASP.Net SQL Server 会话状态与持久会话状态

  2. 2

    是否可以共享 SQL Server 数据库以在 Asp.Net Web Forms 中存储会话状态

  3. 3

    ASP.NET在应用程序数据库中存储会话状态

  4. 4

    在AWS RDS上使用ASP会话状态数据库

  5. 5

    在AWS RDS上使用ASP会话状态数据库

  6. 6

    从数据库返回某些值的安全方法(SQL SERVER和ASP.NET)

  7. 7

    发布后将asp.net mvc 4本地数据库转换为sql数据库

  8. 8

    ASP.NET_SessionId超时时未生成其他会话

  9. 9

    在 sql 命令中使用时,会话值未从数据库获取任何数据

  10. 10

    使用ASP.NET将Excel数据导入到SQL数据库

  11. 11

    从ASP.net SQL数据库检索数据到amchart

  12. 12

    从文本框asp.net C#将数据保存到sql数据库

  13. 13

    ASP.NET注册页:无法在sql数据库中插入数据

  14. 14

    ASP.NET MVC会话状态超时

  15. 15

    不断丢失会话状态ASP.NET

  16. 16

    ASP NET MVC 5会话状态

  17. 17

    .net检查数据集是否与sql数据库不同

  18. 18

    .NET数据库连接状态

  19. 19

    如何从Asp.Net中的SQL数据库引用SQL路径的jQuery SlideShow

  20. 20

    将ASP.NET身份存储移动到EF Sql数据库

  21. 21

    如何从ASP.NET API使用SQL Azure数据库?

  22. 22

    在asp.net中访问sql数据库的有效方法是什么

  23. 23

    使用WebForms的ASP.Net Identity到现有SQL数据库

  24. 24

    无法从ASP.NET中的SQL数据库准确获取值

  25. 25

    如何将ASP.NET MVC数据库从LocalDb传输到SQL Server?

  26. 26

    具有SQL Server数据库连接功能的ASP.Net Web服务

  27. 27

    使用SQL Server CE数据库慢速查询的C#/ ASP.NET网站

  28. 28

    将图像插入ASP.NET中的本地SQL Server数据库

  29. 29

    通过asp.net从多个网页访问SQL Server数据库

热门标签

归档