您的要求与我的服务器缓存动态报告的情况非常相似,但相反。
我有需要很长时间才能生成的按需统计报告,因此如果有人已经请求了该页面,则将提供缓存页面而不是重新生成它。
您的情况是,一旦提供了一个页面,就不要再提供它了。
无论哪种方式,我们都需要在每个页面上都有一个持久的标志或签名。该标志或签名必须位于持久数据存储中。
管理无数可能的页面
如果您必须像我一样管理无数页面,因为按需 http 参数驱动的动态页面的数量是无限的,您不能拥有简单的单个持久标志。我有一个例程将 http post/get 请求参数压缩成一个唯一的签名。该签名被保留。这样当请求进来时,http 参数就会通过这个签名生成器运行,并将生成的签名与持久数据存储进行比较,以搜索签名是否已经存在。
就我而言,如果签名存在,我会提供缓存页面。在您的情况下,如果签名存在,则会显示错误页面。
受时间事件影响的先到先得
但是,在我们这两种情况下,“首次提供的页面”都可能受到时间事件的影响。就我而言,当上传新数据时 - 该签名已过时。所以,我必须确保我的统计信息模式是基于时间的——数据加载时间或事件时间。因此签名有两个组成部分,http 参数签名和请求实体的事件/加载时间。如果签名匹配,但存储在数据库中的请求实体的最新时间大于签名中持久化的时间,则表示该请求被视为“新页面”。
您必须自己决定如何设计有助于生成最短签名的 http 参数,并决定哪些参数可以使页面独一无二。
关于持久化存储,因为我已经使用 oracle 来存储统计信息,所以我也使用相同的 oracle 数据库来持久化签名。否则,我认为 hsqldb 可能是一个很好的解决方案。
签名策略
签名表将包含三个字段:事件日期时间、所有者电报、唯一密钥参数。
为了防止表格超出当前签名,在签名比较期间会覆盖过时的签名。我还有一份删除过时签名的工作。
通过放置一个带有空日期时间的参数,可以非常简单地管理多用户访问。就我而言,我可以向自己保证请求日期时间是唯一的,因此我实际上将请求日期时间用作所有者电报。第一个幸运的人(但在我的情况下是不幸的第一个需要等待未缓存报告的用户)竞相到表并创建唯一的 paramsig 将导致后续尝试被数据库系统抛出。空日期时间通知正在保留一个参数,稍后将填写。在您的情况下,您可能可以跳过该步骤,只使用 paramsig、ownersemaphore。
但是,如果您在多服务器环境中,则需要为 owneremaphore 设计一个复合键,例如服务器 id + 请求时间。
我不确定 hsqldb 是否能够管理并发。我只在oracle和sqlserver上做过这个策略。