首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将会话持久化到DB

将会话持久化到DB
EN

Stack Overflow用户
提问于 2012-02-06 23:37:05
回答 1查看 445关注 0票数 0

我的架构师想知道为什么我们需要将每个用户的会话持久化到DB,而不是仅仅使用cookie。我从没见过有人只吃饼干。

通常,我将会话ID保存在cookie中,然后使用它对Id键下的会话记录执行CRUDS。

我的意思是,我不明白在没有proc的情况下,您如何才能完成会话状态。我总是通过一个自定义表来完成会话状态,其中包含了一些常规字段,比如IsLoggedIn、IsClosed、IsNew、IPAddress、Browser等等。

是否有人在电子商务站点上进行会话状态而不将其保存在DB中?

更新

这就是我在一个电子商务网站工作的另一个地方做事情的方式,这个网站的500+页面一个月内就有点击量:

代码语言:javascript
运行
复制
public USession CreateNewSession(int userID)
{
    string ipAddress = GetCurrentRequestIPAddress(context.Request);

    USession newSession = USession.NewSession();
    newSession.IpAddress = ipAddress;
    newSession.UserID = customerID;
    newSession.Browser = context.Request.UserAgent ?? string.Empty;

    if (context.Request.UrlReferrer != null)
    newSession.Referer = context.Request.UrlReferrer.ToString();
    else
    newSession.Referer = string.Empty;

    InsertSession(newSession);

    return newSession;
}



public USession CreateNewSession(int userID)
{
    string ipAddress = GetCurrentRequestIPAddress(context.Request);

    USession newSession = USession.NewSession();
    newSession.IpAddress = ipAddress;
    newSession.UserID = customerID;
    newSession.Browser = context.Request.UserAgent ?? string.Empty;

    if (context.Request.UrlReferrer != null)
         newSession.Referer = context.Request.UrlReferrer.ToString();
    else
         newSession.Referer = string.Empty;

    InsertSession(newSession);

    return newSession;
}



public USession GetSession()
{
    // existing sessionId this session?
    HttpCookie cookie = context.Request.Cookies["usessionId"];

    if (cookie == null || string.IsNullOrEmpty(cookie.Value))
    session = CreateNewSession(0);
    else
    {
        string sessionID = cookie.Value;

        session = GetSession(sessionID);

        if (session == null) 
            session = CreateNewSession(0);
        else if (session.IsClosed > 0) 
            session = CreateNewSession(session.UserID);
    }

    if (session.LastAccessed < DateTime.Now.AddHours(-1)) session.LoggedIn = false;

    if (session.LastDestination.Equals("lesson"))
        session.LastDestPageDestinationID = ContextValue(context, "lessonid");
    else
        session.LastDestPageDestinationID = 0;

    if (session.IsNew) session.FirstDestination = session.LastDestination;

    SaveSession();

    return session;
}



private void SaveSession()
{
    session.LastAccess = DateTime.Now;
    session.LastDest = string.Empty;

    db.UpdateSession(session);

    if (!cookieIsSet)
    {
        // add a session cookie for this current session
        HttpCookie cookie = CreateSessionCookie("usessionId", session.SessionID, 365);

        if (session.LastDest.Equals("logout", StringComparison.OrdinalIgnoreCase))
            cookie.Value = string.Empty;

        if (session.LastDest.Equals("lessonOrder")) return;

        context.Response.SetCookie(cookie);
    }
}


internal void UpdateSession(USession s)
{
    using (ourConnection conn = CreateConnection("UpdateSession"))
    {
        conn.CommandText = @"update csession set
            closed = @closed,
            userID = @customerID,
            lastAccess = @lastAccess,
            lastDestination = @lastDest,
                        orderId = @OrderId,
            IsloggedIn = @isLoggedIn;

        conn.AddParam("@id", s.Id);
        conn.AddParam("@closed", s.Closed);
        conn.AddParam("@userID", s.UserID);
        conn.AddParam("@lastAccess", s.LastAccess);
        conn.AddParam("@firstDestination", s.FirstDestination);
        conn.AddParam("@lastDestination", s.LastDestination);
        conn.AddParam("@isLoggedIn", s.IsLoggedIn);
        conn.AddParam("@orderID", s.OrderID);

        try
        {
            conn.ExecuteNonQuery();

        }
        catch (Exception ex)
        {
            LogException(ex);
        }
    }
}


public HttpCookie CreateSessionCookie(string cookieValue, string uSessionID, double daysTillExpiration)
{
    HttpCookie cookie = new HttpCookie("usessionid", uSessionID);
    cookie.Expires = DateTime.Now.AddDays(daysTillExpiration);
    cookie.Path = "/";

    return cookie;
}

因此,我们将在整个代码中使用内存中的USession自定义对象来检查loggedIn,强制关闭他们的会话,以及基于当前会话的各种东西。

同样在我们的Application_Error in global.asax中,我们将记录当前的sessionId,以跟踪错误。

代码语言:javascript
运行
复制
HttpCookie cookie = Request.Cookies["usessionid"];
if (cookie != null)
{
    logger.Variables = "<b>uSessionID:</b> " + cookie.Value;

    if (cookie.Value.Length > 0)
        logger.USessionID = GetUSessionID(cookie.Value);
}
EN

回答 1

Stack Overflow用户

发布于 2012-02-06 23:41:33

ASP.NET会话有三种可能的状态:

  • 关闭(我喜欢的)-根本不使用任何会话
  • InProc -会话存储在web服务器的内存中。如果您在web场中运行,则速度快,但不方便,因为web场的每个节点都将有不同的会话副本,您可能会遇到冲突。
  • 程序之外的会话存储在运行ASP.NET会话状态窗口服务的专用服务器的内存中。对于网络农场场景很好,但是不够可靠,因为会话仍然保存在某些服务器的内存中,这些服务器可能无法幸免于崩溃。
  • server会话将持久化在SQL服务器中。非常可靠,适合于网络农场。问题在于性能。它将比以前的模式慢,因为会话现在被保存在数据库中。

这3种模式在下列条款中都有深入的讨论。

您选择的模式是在web.config中配置的,它对您的代码完全透明,您只需使用Session["someKey"]来处理会话,这只是底层存储机制的不同之处。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9168968

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档