【问题标题】:Java web application stalls at slow MySQL queriesJava Web 应用程序在缓慢的 MySQL 查询中停止
【发布时间】:2011-08-13 22:27:57
【问题描述】:

我有一个使用 Java servlet 编写的 Web 应用程序。我使用 Tomcat 7 作为我的 servlet 引擎,但之前使用过 Glassfish 并且遇到了完全相同的问题。

相关页面有一个“统计”部分,每 5 分钟更新一次。由于所涉及的 MySQL 表的大小,生成统计信息大约需要 30 秒。

当我加载页面时,我会显示缓存的统计信息。呈现页面中的所有内容后,我刷新然后关闭输出流。然后我更新统计数据。这样,用户无需等待大约 30 秒即可加载页面并在页面已完全发送后更新统计信息。

问题是,如果我在运行查询的同时刷新页面,页面在查询完成之前不会加载,这意味着虽然初始用户没有任何延迟,但之后有很长的时间延迟。

为什么应用程序会有效地停止? Tomcat 是否应该能够使用另一个工作线程来处理请求,即使一个线程仍然很忙?

谢谢。

【问题讨论】:

  • 你把问题说得很好。但是我们仍然需要知道您是如何创建执行查询的。我怀疑问题出在阻止所有人的同步方法上。分享一些代码!

标签: java tomcat jakarta-ee servlets


【解决方案1】:

可能发生的情况是您的数据在更新期间被“锁定以供更新” - 这完全取决于重新计算数据的方式。

解决此问题的一个好方法是将新计算放入一个单独的数据区域,然后在全部完成后切换到使用新数据。实现这一点的一种方法是使用数据库视图和版本号,如下所示:

create table my_statistics (
  id int not null primary key auto_increment,
  version int not null,
  -- other columns with your data
);

create table stats_version (current_version int); -- holds just one row

create view stats as
select * 
from stats_version v
join my_statistics s on s.version = v.current_version);

将您的新统计数据放入表中,版本号为 current_version + 1。在完成所有计算之后。然后一个简单的update stats_version set current_version = current_version + 1 将切换到使用新数据。最后一条语句只需几毫秒即可执行,因此锁定等待时间非常短。

切换后,您可以删除旧的统计数据以节省空间。

使用“切换”方法进行更新和“原子更新” - 更新“立即且完全”发生,因此用户看不到部分更改的数据集。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-31
    • 2011-08-04
    • 2021-06-13
    • 2012-05-04
    • 2012-01-15
    • 1970-01-01
    相关资源
    最近更新 更多