访问计数器的 Sql 查询未按预期工作

问题描述

以下经典的asp代码用于统计一个网站每天的页面访问量。然后检查最后一条记录的日期:

  • 如果日期更改,则插入新行
  • 如果日期未更改,则更新之前的记录

然而,每天都有多个不需要的记录,重复日期有 1 次或 2 次或 3 次访问,还有一个真实记录,比如在同一日期访问了 10000 次。重复记录的可能原因是什么?

recordset.open "select top 1 id from visit order by id desc",objcon
    if recordset("mdate")=today then
    
        sql="update visit set counter=counter+1 where id=" & recordset("id")
        objcon.execute sql
        
        else
        
        sql="insert into visit (mdate,counter) values ('" & today & "','1')"
        objcon.execute sql
    
    end if
recordset.close

解决方法

这听起来像是竞争条件。同一个id同时有两次访问。他们都运行查询并看到 id 不在表中。瞧!他们都决定插入一个新行。你会得到重复。

有几种方法可以解决这个问题。一种是在进程期间锁定表。我想我更喜欢以下内容:

  • (id,date) 上定义唯一索引,以便数据库确保唯一性。
  • 尝试 insert 计数为 1 的新行。
  • 如果 insert 失败,则将计数更新 1。