【问题标题】:ASP.NET Universal Providers: Session state doesn't get deleted?ASP.NET 通用提供程序:会话状态不会被删除?
【发布时间】:2012-12-14 04:59:00
【问题描述】:

我们刚刚从旧的 ASP.NET 成员(从 MVC3)迁移到新的 ASP.NET 通用提供程序,因为我们的 SQL 目标是 Azure SQL。迁移期间的 SQL 脚本非常痛苦!无论如何,我们将会话状态设置为 SQL(即 web.confg 中的<sessionState mode="Custom")。

现在,如果网站意外关闭,(比如调试 => 停止)当我们恢复时,我们会收到错误: Violation of PRIMARY KEY constraint 'PK__Sessions__C9F492908756A0EE'. Cannot insert duplicate key in object 'dbo.Sessions'. The duplicate key value is (<randomstring>). The statement has been terminated.

正如预期的那样,我确认会话确实在 [db].[SessionId] 表内的数据库中具有相同的条目,并带有主键。

问题:谁负责删除该数据库条目?我知道如果正确启动注销,它应该被代码清除。但是如果它已经存在,不应该有一些自动错误处理(在会员本身中)吗?如果是,为什么不触发?如果没有,如何添加?

【问题讨论】:

    标签: session asp.net-membership


    【解决方案1】:

    清除过期会话是 ASPState 数据库中 SQL Server 代理的工作。您不必添加它。

    Session Expiration - SqlSessionStateStore

    更新:2012 年 12 月 19 日

    DefaultSessionStateProvider 中,每个请求中的过期会话都会被清除。

    public override void InitializeRequest(HttpContext context)
    {
        this.PurgeIfNeeded();
    }
    
    private void PurgeExpiredSessions()
    {
        bool flag;
        SessionEntities sessionEntity = ModelHelper.CreateSessionEntities(this.ConnectionString);
        try
        {
            DateTime utcNow = DateTime.UtcNow;
            IQueryable<Session> expiredSessions = QueryHelper.GetExpiredSessions(sessionEntity);
            IEnumerator<Session> enumerator = expiredSessions.GetEnumerator();
            try
            {
                while (true)
                {
                    flag = enumerator.MoveNext();
                    if (!flag)
                    {
                        break;
                    }
                    Session current = enumerator.Current;
                    sessionEntity.DeleteObject(current);
                }
            }
            finally
            {
                flag = enumerator == null;
                if (!flag)
                {
                    enumerator.Dispose();
                }
            }
            sessionEntity.SaveChanges();
        }
        finally
        {
            flag = sessionEntity == null;
            if (!flag)
            {
                sessionEntity.Dispose();
            }
        }
    }
    
    private void PurgeIfNeeded()
    {
        this.PurgeExpiredSessions();
    }
    

    【讨论】:

    • 谢谢;当数据库在 Azure SQL 上时,您知道如何启用该作业吗?另外,我认为较新的通用提供程序不会添加任何存储过程(与以前不同)。所以这使得能够运行这样的工作更加令人费解......
    • 我更新了答案。如果您使用 Azure,您可能需要了解如何:将 ASP.NET 会话状态存储在缓存中windowsazure.com/en-us/develop/net/how-to-guides/cache/…
    猜你喜欢
    • 1970-01-01
    • 2012-08-23
    • 2013-07-21
    • 2015-03-10
    • 2011-06-23
    • 2015-06-18
    • 2013-03-12
    • 2011-06-09
    • 1970-01-01
    相关资源
    最近更新 更多