17

ASP.NET 4.0 SQL 会话状态机制是否向后兼容用于会话状态的 ASP.NET 2.0 架构,或者我们应该/必须为我们的 ASP.NET 4.0 应用程序创建一个单独且不同的会话状态数据库?

无论如何,我倾向于后者,但 2.0 数据库似乎可以正常工作,尽管我想知道 2.0 和 4.0 版本的 ASP.NET 之间的 ASPState 数据库架构/过程之间是否存在任何实质性差异。谢谢你。

4

1 回答 1

25

任何人都没有快速回答这个问题,所以我做了一些挖掘。我使用来自 .NET 2.0 的工具生成了一个ASPState数据库aspnet_regsql.exe,然后我使用相同的工具但来自 .NET 4.0 做了同样的事情。然后,我从每个生成的 SQL Server 数据库生成脚本,并使用比较工具来隔离差异。

我发现: 从 .NET 2.0 到 .NET 4.0 版本的架构之间的唯一实质性区别是存储过程。ASPStatedbo.DeleteExpiredSessions 这是由同样由该工具安装的 SQL Server 代理计划作业定期调用的存储过程。

因此,似乎ASPState 2.0 和 ASPState 4.0 的架构是完全兼容的,因此从技术角度来看,没有必要隔离 ASP.NET 2.0 和 ASP.NET 4.0 会话状态——但我可能还是会这样做.

(这个发现有点令人惊讶,因为 ASPState 从 .NET 1.1 到 .NET 2.0 发生了很大变化。)

每个版本的更改存储过程的详细信息:

.NET 2.0 ASPState DeleteExpiredSessions 存储过程:

CREATE PROCEDURE dbo.DeleteExpiredSessions
AS
    DECLARE @now datetime
    SET @now = GETUTCDATE()

    DELETE [ASPState].dbo.ASPStateTempSessions
    WHERE Expires < @now

    RETURN 0   
GO

.NET 4.0 ASPState DeleteExpiredSessions 存储过程:

CREATE PROCEDURE dbo.DeleteExpiredSessions
AS
    SET NOCOUNT ON
    SET DEADLOCK_PRIORITY LOW 
    DECLARE @now datetime
    SET @now = GETUTCDATE() 
    CREATE TABLE #tblExpiredSessions 
    ( 
        SessionID nvarchar(88) NOT NULL PRIMARY KEY
    )
    INSERT #tblExpiredSessions (SessionID)
        SELECT SessionID
        FROM [ASPState].dbo.ASPStateTempSessions WITH (READUNCOMMITTED)
        WHERE Expires < @now
    IF @@ROWCOUNT <> 0 
    BEGIN 
        DECLARE ExpiredSessionCursor CURSOR LOCAL FORWARD_ONLY READ_ONLY
        FOR SELECT SessionID FROM #tblExpiredSessions 
        DECLARE @SessionID nvarchar(88)
        OPEN ExpiredSessionCursor
        FETCH NEXT FROM ExpiredSessionCursor INTO @SessionID
        WHILE @@FETCH_STATUS = 0 
            BEGIN
                DELETE FROM [ASPState].dbo.ASPStateTempSessions WHERE
                    SessionID = @SessionID AND Expires < @now
                FETCH NEXT FROM ExpiredSessionCursor INTO @SessionID
            END
        CLOSE ExpiredSessionCursor
        DEALLOCATE ExpiredSessionCursor
    END 
    DROP TABLE #tblExpiredSessions
RETURN 0     
GO

至于为什么需要进行上述更改,我找到了以下 MSDN 博客文章:

摘录,参考旧程序:

...
这将对所有过期记录进行锁定以进行删除,并且这些锁定可能会升级为页面锁定。当标记为删除的记录数量增加时,这可能会导致与其他“会话状态写入语句”的死锁。默认情况下,这个存储过程应该每分钟运行一次。 ...

因此,对于 ASP.NET 2.0 应用程序,更新版本的存储过程也可能是可取的。

我从博文中学到的另一件事是我不知道的:ASP.NET 4.0 会话状态机制现在提供了压缩compressionEnabledsessionState 元素(ASP.NET 设置架构)上搜索。


最后,我还刚刚在ASP.NET Side-by-Side Execution Overview中从 Microsoft 找到了一些相关的内容。摘抄:

...
如果使用 SQL Server 管理会话状态,则安装在同一台计算机上的所有版本的 ASP.NET(.NET Framework)可以共享安装了最新版本的 ASP.NET 的 SQL 状态服务器. 会话状态的架构在所有版本的 ASP.NET 中都是相同的。

(虽然在实现上存在一些不特定于模式的差异。)

于 2010-06-07T14:17:44.680 回答