ASP Application
Application 对象的集合、Lock / Unlock、Contents 与 StaticObjects。
Key PointsApplication 有 Contents(变量)和 StaticObjects(object 声明的对象)两个集合,改数据必须加锁。
两个集合
| Collection | Holds |
|---|---|
Contents | Application("x") = ... 存进去的所有变量 |
StaticObjects | Global.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里初始化 - 计数器 —— 访问量、在线人数
- 缓存 —— 把不常变的查询结果放进去,减少数据库压力
- 不要放 —— 用户相关数据(会串号)、大对象(占内存)
两个集合
| 集合 | 内容 |
|---|---|
| 变量集合 | Application("x") = ... 存进去的所有变量 |
| 对象集合 | Global.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 会让所有其他请求排队等待。锁住的时间越长,站点的并发能力越差——一个慢查询锁住整个站点,所有用户一起卡住。
读的时候要不要锁
ASP
<%
' 只读一般不用锁:读到旧值不会导致数据错误
Response.Write Application("siteName")
' 但「读出来判断再写」必须锁
Application.Lock
If Application("hits") < 10000 Then
Application("hits") = Application("hits") + 1
End If
Application.Unlock
%>判断和写入之间有空隙,不锁就会出现「两个请求都判断通过、都写」的情况。凡是「读—判断—写」的组合,必须整体加锁。
清理
ASP
<%
Application.Contents.Remove("tempData")
Application.Contents.RemoveAll
Application.Lock
Application.Contents.RemoveAll ' 批量清理也要加锁
Application.Unlock
%>Application 只在单个 IIS 进程里有效。应用池回收后全部清空,多台服务器之间也不共享。需要跨重启、跨机器共享的状态必须放数据库或缓存服务。典型用法
- 站点配置 —— 名称、版本、开关,
Global.asa里初始化 - 计数器 —— 访问量、在线人数
- 缓存 —— 把不常变的查询结果放进去,减少数据库压力
- 不要放 —— 用户相关数据(会串号)、大对象(占内存)