ASP Application

Application 对象的集合、Lock / Unlock、Contents 与 StaticObjects。

Intermediate
Key PointsApplication 有 Contents(变量)和 StaticObjects(object 声明的对象)两个集合,改数据必须加锁。

两个集合

CollectionHolds
ContentsApplication("x") = ... 存进去的所有变量
StaticObjectsGlobal.asa 里 <object runat=Server> 声明的对象
ASP
<%
    Application("siteName") = "我的站点"
    Application("version") = "1.2.0"

    Response.Write Application.Contents.Count & " 个应用变量<br>"

    Dim k
    For Each k In Application.Contents
        Response.Write k & " = " & Application(k) & "<br>"
    Next
%>
Output
2 个应用变量
siteName = 我的站点
version = 1.2.0

加锁的粒度

ASP
<%
    ' 好:只包住必要的读改写
    Application.Lock
    Application("hits") = Application("hits") + 1
    Application.Unlock

    ' 不好:锁住了整个页面的逻辑
    Application.Lock
    Dim conn
    Set conn = Server.CreateObject("ADODB.Connection")
    conn.Open connStr
    ' ... 几十行查询
    Application.Unlock
%>

Lock makes every other request wait. The longer it is held, the worse concurrency gets: one slow query inside the lock stalls the entire site.

读的时候要不要锁

ASP
<%
    ' 只读一般不用锁:读到旧值不会导致数据错误
    Response.Write Application("siteName")

    ' 但「读出来判断再写」必须锁
    Application.Lock
    If Application("hits") < 10000 Then
        Application("hits") = Application("hits") + 1
    End If
    Application.Unlock
%>

There is a gap between the check and the write, so without a lock two requests can both pass the check and both write. Any read-check-write sequence must be locked as a whole.

清理

ASP
<%
    Application.Contents.Remove("tempData")
    Application.Contents.RemoveAll
    Application.Lock
    Application.Contents.RemoveAll           ' 批量清理也要加锁
    Application.Unlock
%>
Application exists only inside one IIS process: an app-pool recycle clears it and multiple servers do not share it. State that must survive restarts or span machines belongs in a database or cache.

典型用法

  • 站点配置 —— 名称、版本、开关,Global.asa 里初始化
  • 计数器 —— 访问量、在线人数
  • 缓存 —— 把不常变的查询结果放进去,减少数据库压力
  • 不要放 —— 用户相关数据(会串号)、大对象(占内存)

Friends & Partners