1
votes

We just migrated from the older ASP.NET membership (from MVC3) to the new ASP.NET universal providers since our SQL target is Azure SQL. The SQL scripts during that move were - painful! Anyway, we set session state to SQL (i.e. <sessionState mode="Custom" in web.confg).

Now if the site goes down unexpectedly, (say debugging => stop) when we resume we get the error: 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.

As expected, I confirmed that the session does indeed have the same entry in the db inside the [db].[SessionId] table with the primary key.

Question: Who is responsible for deleting that db entry? I understand if a logout is properly initiated it should get wiped out by code. But shouldn't there be some automatic error handling (in Memberships itself) in case it already exists? If yes, why isn't it triggered? If no, how can I add it?

1

1 Answers

1
votes

Purging expired sessions is SQL Server Agent's job included in ASPState database. You do not have to add it.

Session Expiration - SqlSessionStateStore

Update: 12/19/2012

In DefaultSessionStateProvider, expired sessions are purged in every request.

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();
}