无限循环数据库检查
Posted
技术标签:
【中文标题】无限循环数据库检查【英文标题】:infinite loop database check 【发布时间】:2013-05-14 05:39:46 【问题描述】:我正在使用 JDBC,需要不断检查数据库是否有变化的值。
我目前有一个无限循环运行,内部循环迭代一个变化的值,每次迭代都检查数据库。
public void runInBG() //this method called from another thread
while(true)
while(els.hasElements())
Test el = (Test)els.next();
String sql = "SELECT * FROM Test WHERE id = '" + el.getId() + "'";
Record r = db.getTestRecord(sql);//this function makes connection, executeQuery etc...and return Record object with values
if(r != null)
//do something
我认为这不是最好的方法。
我想的另一种方式是相反的,继续迭代数据库。
更新
感谢您提供有关计时器的反馈,但我认为它不会解决我的问题。 一旦数据库发生变化,我需要根据变化的值(示例代码中的“els”)几乎立即处理结果。
即使数据库没有变化,它仍然需要不断检查变化的值。
更新 2
好的,对于任何对答案感兴趣的人,我相信我现在有了解决方案。基本上解决方案不是为此使用数据库。加载、更新、添加等……只需要从数据库到内存。 这样您就不必经常打开和关闭数据库,您只需在对数据库进行更改时处理数据库,并将这些更改反映到内存中,并且只处理当时内存中的任何内容。 当然,这会占用更多内存,但性能是这里的绝对关键。
至于定期的“计时器”答案,很抱歉,但这根本不对。没有人回答为什么使用计时器可以解决这种特殊情况。
但再次感谢您的反馈,它仍然很有帮助。
【问题讨论】:
(+1) 好问题...我能看到这样做的唯一方法是在数据库端添加某种触发器。我也不喜欢这样,因为它不受程序的控制,可能过于具体。 您的应用程序控制是否也更新和插入? 是的,Peeyush。我编写了类来处理所有数据库交互。 嗨 Jaco,请查看更新的解决方案。 您应该发布 update2 作为答案并接受它! 【参考方案1】:另一种可能性是使用ScheduledThreadPoolExecutor
。
您可以实现一个包含您的逻辑的Runnable
,并将其注册到ScheduledExecutorService
,如下所示:
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
executor.scheduleAtFixedRate(myRunnable, 0, 5, TimeUnit.SECONDS);
上面的代码创建了一个ScheduledThreadPoolExecutor
,它的池中有10个线程,并注册了一个Runnable
,它将在5秒内立即开始运行。
要安排您的可运行文件,您可以使用:
scheduleAtFixedRate
创建并执行一个周期性动作,该动作在给定的初始延迟后首先启用,然后在给定的周期内启用;也就是说,执行将在 initialDelay 之后开始,然后是 initialDelay+period,然后是 initialDelay + 2 * period,依此类推。
scheduleWithFixedDelay
创建并执行一个周期性操作,该操作首先在给定的初始延迟之后启用,随后在一个执行的终止和下一个执行的开始之间具有给定的延迟。
和here你可以看到ThreadPoolExecutor
的优点,看看它是否符合你的要求。我建议这个问题:Java Timer vs ExecutorService? 也是为了做出正确的决定。
【讨论】:
【参考方案2】:将while(true)
保留在runInBG()
中是个坏主意。你最好去掉那个。相反,您可以使用 Scheduler/Timer(使用 Timer 和 TimerTask)定期调用 runInBG()
并检查数据库中的更新。
【讨论】:
你可以跳过Timer
和TimerTask
的编码,方法是使用像quartz这样处理计划操作的框架
同意使用调度程序进行调度是可行的方法,但是由于 OP 没有提到使用第三方库的任何内容,因此使用标准 java 类似乎是一个不错的选择!如果 OP 可以使用 3p 库,则可以稍后实施调度!
仅供参考,我自己是 Quartz 用户! :)
仅仅添加信息以防手动配置Timer
会让人头疼,因为像这样的框架已经处理了很多问题。是的,我是石英用户(免责声明:我与图书馆开发无关,也与任何客户支持无关,只是一个快乐的用户)。
这必须不断检查,因为当数据库中发生任何更改时,必须处理结果。我不明白如何使用计时器来解决这个问题。【参考方案3】:
你可以使用计时器--->
Timer timer = new Timer("runInBG");
//Taking an instance of class contains your repeated method.
MyClass t = new MyClass();
timer.schedule(t, 0, 2000);
【讨论】:
【参考方案4】:正如您在上面的评论中所说,如果应用程序控制更新和插入,那么您可以创建一个框架来通知“BG”线程或进程有关数据库中的更改。通知可以通过网络通过 JMS 或使用观察者模式的内部 VM 或本地和远程通知。
你可以有通用的通知消息(它可以是本地通知的类或远程通知的文本消息)
<Notification>
<Type>update/insert</Type>
<Entity>
<Name>Account/Customer</Name>
<Id>id</Id>
<Entity>
</Notification>
【讨论】:
【参考方案5】:为了避免“忙循环”,我会尝试使用触发器。 H2 还支持DatabaseEventListener API,这样您就不必为每个表创建触发器。
这可能并不总是有效,例如,如果您使用远程连接。
【讨论】:
【参考方案6】:更新 2
好的,对于任何对答案感兴趣的人,我相信我现在有了解决方案。基本上解决方案不是为此使用数据库。加载、更新、添加等……只需要从数据库到内存。这样您就不必经常打开和关闭数据库,您只需在对数据库进行更改时处理数据库,并将这些更改反映到内存中,并且只处理当时内存中的任何内容。当然,这会占用更多内存,但性能是这里的绝对关键。
【讨论】:
以上是关于无限循环数据库检查的主要内容,如果未能解决你的问题,请参考以下文章