我正在用jersey设计一个javaweb应用程序,在mysql数据库中有一个日期时间字段“future\u time”。我也是一个在同一个表中有一个状态字段设置为挂起。如果当前时间>=未来时间,我想更新status字段为completed in db。好像我想安排一个活动。
其次,如果当前时间<未来时间,并且如果我更新了未来时间值,我想重新安排上一个事件。
当前,每当我获取status字段时,我都会检查它是否挂起,如果它挂起,那么我会检查future\u time是否<=current\u time,如果是,那么我会将db中的status字段更新为completed。但这里面有个问题。这只会在我获取状态字段时更新它。因此,如果我在很长一段时间之后(在未来的\时间之后)获取status字段,那么它将在那一刻被更新,在db中保存不正确的记录。
有人能给我一个更好的方法来实现这个目标吗?
2条答案
按热度按时间2j4z5cfb1#
计算截止日期前经过的时间
对于JDBC4.2和更高版本,使用现代的java.time类检索日期时间。
获取当前时刻。
计算经过的时间。
计划事件
使用现代的executor框架,而不是遗留的
Timer
班级。在servlet或jakarta.ee(javaee)环境中尤其如此。定义你的执行者,特别是
ScheduledExecutorService
. 我们只需要一个线程来完成这个任务。让执行器等待一定的时间,然后运行代码检查数据库中的状态。
或者,您可以捕获
ScheduledFuture
由此返回schedule
声明。然后可以监视完成状态。在你的
Runnable
,从数据库中检索当前状态记录。如果需要,安排另一次执行,使用新的当前时刻重新计算等待时间。servlet web容器
对于没有完整jakarta.ee堆栈的servlet web容器,如tomcat或jetty,上面的讨论适用。
此外,您还需要编写一个实现
ServletContextListener
接口,您可以设置和拆除您的执行器服务。你需要优雅地拆除executor服务,这样它的后台线程就不会在你的web应用关闭后很长一段时间内愉快地继续运行了。雅加达ee
如果在一个完整的jakarta.ee堆栈(如glassfish)中,这项工作要容易得多。
上面看到的executor服务可以自动化,并代表您进行设置和拆卸。使用jsr 236:concurrency utilities for javatm ee中定义的并发实用程序。这已经被讨论过很多次了,所以搜索堆栈溢出以获取更多信息。
关于java.time
java.time框架内置于Java8及更高版本中。这些类取代了旧的遗留日期时间类,例如
java.util.Date
,Calendar
, &SimpleDateFormat
.现在处于维护模式的joda time项目建议迁移到java.time类。
要了解更多信息,请参阅oracle教程。和搜索堆栈溢出的许多例子和解释。规格为jsr 310。
您可以直接与数据库交换java.time对象。使用符合jdbc 4.2或更高版本的jdbc驱动程序。不需要线,不需要线
java.sql.*
班级。从哪里获得java.time类?
JavaSE8、JavaSE9、JavaSE10、JavaSE11及更高版本—标准JavaAPI的一部分,带有捆绑实现。
Java9添加了一些次要的特性和修复。
java se 6和java se 7
大部分java.time功能都是通过三个十个后端口后端口移植到Java6和Java7的。
安卓
android包java.time类的更高版本实现。
对于早期的android(<26),threetenabp项目采用了threeten backport(如上所述)。了解如何使用threetenabp…。
threeten额外的项目用额外的类扩展了java.time。这个项目是java.time将来可能添加的一个试验场。您可以在这里找到一些有用的类,例如
Interval
,YearWeek
,YearQuarter
,等等。ftf50wuq2#
你可以用
ScheduledExecutorService
用于在特定的时间间隔、固定的延迟或特定的时间点安排任务。您可以创建
ScheduledExecutorService
比如:然后使用服务安排作业,如:
您也可以使用java定时器实用程序来为将来安排任务,但是java规范说更喜欢
ScheduledExecutorService
. 下面是一个使用计时器调度作业的示例代码。您可以更深入地研究该实用程序以安排重复的任务。另外,一旦完成了所需的工作,不要忘记取消任务。
您也可以为此尝试其他框架,如quartz和spring调度。