我正在建立一个ASP.Net网站。我有一个“购物车”类,用于存储用户购物车中的商品。每次页面重新加载以填充存储在此对象中的购物车项目时,我不想重新查询数据库。存储/保存实例化对象的最佳方法是将它们放在会话中并将会话存储到数据库(我们在SQL Server 2k8上)?看起来大多数人都是通过阅读StackOverflow上的其他帖子来推荐的。我们的网站拥有相当高的流量,因此很容易想象1000个这些对象在任何给定时间都处于活动状态。
我是建立ASP.Net网站的新手。通常的做法是持久保存用户对象(不仅仅是会话或cookie中的简单变量,而是类对象)...也沿着持久对象的行,我打算创建一个静态类,它存储常用的站点范围数据,如作为美国各州的名单......这样做有什么陷阱吗?我不想用脚射击自己。
更新:
我们处于一个服务器场环境中,因此在daatabase中存储会话似乎是不可能的......如果一台服务器出现故障,我们会转到另一台服务器......在这种情况下,会话数据可能会丢失。我们正在考虑使用一个单独的服务器来存储会话,这些服务器可以在我们的服务器场环境中运行,但是我很想将这些实例化的对象存储在内存中。
答案 0 :(得分:2)
您可能需要考虑使用他们称之为AppFabric的新Microsoft技术。它包含分布式缓存功能(以前称为Velocity)。将会话状态持久保存到SQL的问题当然是每次访问会话状态时都会有数据库命中。当然,使用Session对象的问题在于,它仅适用于特定服务器,如果您处于养殖环境中,该服务器会崩溃。 Velocity提供了一个分布式缓存(它也能够与ASP.NET会话数据相当无缝地工作),这是一个分布在许多机器上的内存缓存,所有服务器都可以访问它们。
答案 1 :(得分:2)
会话可能是您的最佳选择。
由于您使用SQL作为Session持有者,因此它将不在进程中,因此您可以在Web场上使用它而不会出现问题。但是,每次引用该对象时,仍会有数据库命中。但是,它是一个高效的数据库命中。
请务必确保您的Cart类是“可序列化的”,否则它将会爆炸进入Session。
答案 2 :(得分:1)
既然你说每次页面加载都不想重新查询数据库,那么会话状态将是一个糟糕的选择 - 因为这正是它所做的(假设你正在使用SQL模式,因为InProc模式赢了不适合网络农场)。实际上,对于每个请求,通常有两次到DB的往返:一个在开始时读取会话对象并更新会话到期时间,另一个在最后更新它。会话还会在页面处于活动状态时对其施加锁定,这对于使用Ajax或框架或用户经常使用多个窗口的网站来说可能是一个问题。
通常,通过在SQL Server中自己存储对象,从性能和可伸缩性的角度来看,您会更好。使用这种方法,您可以使用SqlDependency
或SqlCacheDependency
来缓存对象,以避免往返。在Web场中,使用cookie通常有助于确保所有内容都保持同步,因为从更新数据库到通过通知在所有服务器上清除缓存条目时可能会有轻微的延迟。 / p>
如果有帮助,我会在书中详细介绍这些类型的问题:Ultra-Fast ASP.NET。
答案 3 :(得分:0)
这可能是过早优化的情况。
在我看来,如果你使用会话状态进行设计,很难创建一个高质量的网站。 HTTP是“无状态的”,尽管存在旨在掩盖这一事实的抽象(例如ASP.NET会话),但您经常会遇到真相。 Session对象是一个用于进行内存缓存的正常工具,但您永远不应指望它是可靠的。换句话说,您可以使用它来优化代码,但是您仍然需要代码来执行完整的数据库检索作为后退。
Session的SQL内存储是尝试解决服务器场问题的一种方法,但是如果您首先尝试避免使用数据库,为什么还要烦恼呢?请记住,尽管您可能会跨请求重复查询相同的购物车数据,但SQL服务器本身可以为您执行大量缓存和优化。它可能没有你想象的那么慢。
就静态数据而言,请谨慎使用。应用程序池回收有时会破坏内存中的数据,您必须非常小心,对需要启动初始化的静态数据的访问是可重入的。
答案 4 :(得分:0)
您可以在网络服务器场上使用粘性会话(亲和力),并将内容粘贴到会话中吗?