我在Java应用程序中有一份工作,该工作每隔5分钟使用spring JDBC从Oracle数据库读取数据。 Java应用程序正在WebSphere Application Server上运行。它加载状态为“ X”的记录,在加载记录后将记录的状态更改为“ Y”。我们一次读取1万条记录,并为某些处理向10个线程中的每个线程提供1k条记录。
处理完每条记录后,记录状态将变为“ Z”。现在,如果在处理诸如outOfMemory错误之类的记录时出现问题并且WebSphere发生故障,则记录状态仍为“ Y”。
因此,下次服务器启动时,作业将开始读取状态为“ X”的记录。但是,状态为“ Y”的未处理记录将永远不会被加载。那么,当WebSphere出现故障时,有什么方法可以调用方法吗?我可以在其中编写一段代码,使未处理的记录的状态变为“ X”,以便下次服务器启动时可以选择它们。

最佳答案

如果应用程序遇到了OutOfMemoryError,实际上没有可靠的方法让您确保在关闭之前执行某些代码(实际上,OutOfMemoryError不会使进程本身死亡,但实际上并不能至关重要-如果您的内存不足,则无法确定在此过程中您将无法执行任何操作)。

您应该做的是摆脱“ Y”状态。只要确保读取项目的作业不会多次执行即可(请参阅下文)。然后,您应该能够读取项目,将其发送给处理,完成后只需将状态设置为“ Z”(最好与处理每个项目的事务相同)。

现在,您无需指定每五分钟开始工作的方式,所以我仅假设您为此使用Spring的调度功能。在这种情况下,只要作业仍在运行,就永远不会被解雇。这意味着您的工作需要跟踪已发送的项目,并等待它们完成后再退出。可以使用ExecutorCompletionService完成。将每个子任务(即1k条记录的大块)发送到相同的ExecutorCompletionService,并在剩余任务更多时轮询完成的任务。当所有子任务都返回后,您可以安全地退出父作业。

另一种执行此操作的方法(如果出于某些特定原因需要“ Y”状态)将是在启动时检查“ Y”记录,例如用@PostConstruct注释的方法中

07-27 19:36