我正在开发的应用程序的任务之一是备份系统上运行的其他应用程序的数据。我想安排此备份过程,以便它可以无人值守运行。我正在使用JEE6 / EJB3.1 Timer实用程序。
我有一个类BackupConfiguration,我使用JPA2持久保存到数据库,JPA2有一个TimerHandle类型的字段。如果用户决定安排备份,我会创建一个新的持久定时器并填充TimerHandle字段。
如果我重新启动服务器一切都很好,定时器重新启动(并且因为所有定时器一下子开火,感到一阵短暂的恐慌),一切都在我离开的时候。
如果我重新部署应用程序(在我开发它时会发生很多事情),所有计时器都会丢失!我愚蠢地认为计时器会与服务器绑定,但事实证明它们与应用程序绑定。
所以,我的问题是,在重新部署中保持计时器的最佳方法是什么?
我能看到的唯一解决方案是存储ScheduleExpression以及带有备份配置的TimerHandle。然后,如果我有一个句柄但没有Timer我重新创建计时器。这个问题的主要问题是它意味着每次应用程序开始查明是否有丢失的计时器时枚举每个计划的实体。目前这不是很多工作,但在未来可能会成为巨大的成本。
答案 0 :(得分:2)
对于GlassFish,--keepstate=true
命令有asadmin redeploy
选项。
它在重新部署之间保留EJB计时器。
有关详细信息,您可以看到:
http://docs.oracle.com/cd/E18930_01/html/821-2418/beahw.html
http://docs.oracle.com/cd/E18930_01/html/821-2416/ggndx.html#SJSASEEAGgkudf
http://docs.oracle.com/cd/E18930_01/html/821-2433/redeploy-1.html#scrolltoc
答案 1 :(得分:1)
似乎大多数(可能是所有)应用程序服务器都使定时器对应用程序而不是服务器持久。这是有道理的,因为当您删除应用程序时,您不希望定时器闲置。在开发过程中它很尴尬,因为NetBeans至少会在重新部署之前删除应用程序,从而失去所有的定时器。
我提出的解决方案是将TimerHandle和调度信息存储在数据库中。当应用程序启动时,它会创建一个TimerRepair单例bean,它在任何需要它的类上调用repairTimers。 repairTimers方法选择所有Schedules,如果他们有TimerHandle尝试恢复Timer。如果定时器恢复引发异常,它将从调度信息重新创建定时器。总的来说,作为一个解决方案并不算太糟糕,如果安排了很多项目,我唯一真正关心的是启动时间过长。