【问题标题】:Incremented DB Field增量数据库字段
【发布时间】:2009-08-13 04:00:10
【问题描述】:

假设我在网站上有一篇文章,我想跟踪文章的浏览量。在 Articles 表中,有 PK ID - int、Name - nvarchar(50) 和 ViewCount - int。每次查看页面时,我都会增加 ViewCount 字段。我担心更新字段时发生碰撞。我可以在存储过程中运行它,其中包含如下事务:

CREATE PROCEDURE IncrementView
(
    @ArticleID int
)
as

BEGIN TRANSACTION

UPDATE Article set ViewCount = ViewCount + 1 where ID = @ArticleID

IF @@ERROR <> 0
BEGIN
    -- Rollback the transaction
    ROLLBACK

    -- Raise an error and return
    RAISERROR ('Error Incrementing', 16, 1)
    RETURN
END

COMMIT

我担心我最终会在此模型中不计算 PageViews。另一种可能的解决方案是日志类型的模型,我实际记录文章的浏览量,并使用函数和视图的组合来获取有关文章浏览量的数据。

【问题讨论】:

    标签: sql tsql transactions


    【解决方案1】:

    可能更好的模型是每小时在应用程序中的某处缓存视图数量,然后以批处理方式更新它们。

    -- 编辑:

    为了详细说明,一个简单的模型可能是:

    1. 对于给定的页面,每个页面加载都会增加一个静态哈希图。同样在每次加载时,检查自“上次更新”以来是否经过了足够的时间,如果是,则执行更新。

    2. 有点棘手,将基值放入 asp.net 缓存 (http://msdn.microsoft.com/en-us/library/aa478965.aspx),当超时时,[实现链接中描述的缓存删除处理程序] 进行更新。设置一个小时的超时时间。

    在这两种模型中,您都将获得页面到计数的静态映射;您将更新每个视图,您还将使用它 - 以及缓存的 db 数量 - 来获取当前的“实时”计数。

    【讨论】:

    • 不,必须是实时的。如果你看一下这个网站,它的浏览量是实时的。
    • 明明可以实时显示,只是不会实时在数据库中。变量可以是静态的。
    • +1 嗯,还不错。你以为我使用的是 asp.net... 幸运的是,我是。在您的模型中,我可以使用 lock() 使静态哈希/缓存项安全。
    • 谢谢,没有理由使用锁; int 操作是原子的。
    【解决方案2】:

    数据库应该能够自动处理单个数字的增量。在可能发生冲突的情况下,应按顺序处理队列上的查询。您更大的问题是,如果有足够的卷将处理所有对同一行的写入。每次写入都会阻塞其后面的读取和写入。如果您担心,我会创建一个简单的程序,它会连续调用 SQL 更新并使用数百个并发线程运行它(增加线程直到您的硬件饱和)。确保尝试 = 最终结果。

    找到一种机制来缓存和/或执行批量更新,就像丝绸建议的那样听起来像是赢家。

    雅各布

    【讨论】:

    • 我喜欢一个测试项目的想法,它可以敲击数据库并检查输出。
    【解决方案3】:

    您无需担心 SQL Server 中单个更新语句中的并发性。
    但是,如果您担心 2 个用户在同一个十分之一秒内打到一张桌子,请记住一天中有 864,000 个十分之一秒。对于提供文章的页面来说,这听起来不会成为问题。

    【讨论】:

      【解决方案4】:

      别害怕!

      此更新是单个(原子)事务 - 您无法获得“冲突”。即使对 IncrementView 的 5,000,000 次调用都在同一时刻访问数据库,它们都会以串行、队列的方式进行处理——这就是你使用数据库引擎的目的——一致性。每次调用都会(至少)在该行上获得一个独占更新锁,因此在当前查询提交之前,后续查询都不能更新该行。

      您甚至不需要使用 BEGIN TRAN...COMMIT。如果更新失败,无论如何也没有什么可回滚的。

      我认为不需要任何应用缓存 - 此更新没有理由需要很长时间,因此不会影响您的应用性能。 [假设它的设计相对较好!]

      【讨论】:

        猜你喜欢
        • 2010-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-15
        • 2011-03-06
        • 2017-08-12
        • 1970-01-01
        相关资源
        最近更新 更多