EJB 计时器服务:WTRN0006W:事务 xxxx 在 120 秒后超时

EJB Timer service: WTRN0006W: Transaction xxxx has timed out after 120 seconds

我们每天 运行 在不同时间有 4 个计时器作业。为此,我们正在使用具有 4 个线程的内部默认持久定时器调度程序。在此批处理作业中,我们检索许多 DB2 table 的内容,然后将每个 table 数据存储在远程服务器或 IBM Cloud Object Store 中的文件中。我们注意到,如果任何一个外部资源(如 DB2 或 SFTP 到远程服务器,或 IBM COS)确实在 120 秒之前做出响应,我们会得到以下异常:

    WTRN0124I: When the timeout occurred the thread with which the transaction is, or was most recently, associated was 
    Thread[WebSphere_EJB_Timer_Service_WorkManager.Alarm Pool : 0,5,WebSphere_EJB_Timer_Service_WorkManager: WAS Scheduler: 
    WebSphere_EJB_Timer_Service]. The stack trace of this thread when the timeout occurred was: 
    java.net.SocketInputStream.socketRead0(Native Method)
    java.net.SocketInputStream.socketRead(SocketInputStream.java:127)
    java.net.SocketInputStream.read(SocketInputStream.java:182)
    java.net.SocketInputStream.read(SocketInputStream.java:152)

发生这种情况时,批处理作业会继续执行下一个 table,但是当完成所有 table 时,它会再次重新启动同一个作业。我们想停止重新启动批处理作业。能否请您帮助我们如何做到这一点。

有几种不同的方法可以实现所需的行为:

1) 增加 bean 的事务超时,以便计时器方法成功完成。这是在 ibm-ejb-jar-ext.xml 部署描述符文件中完成的,看起来像这样将事务超时增加到 600 秒:

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar-ext xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://websphere.ibm.com/xml/ns/javaee"
    xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-ejb-jar-ext_1_0.xsd" version="1.0">
  <session name="<your timer bean name>">
    <global-transaction transaction-time-out="600"/>
  </session>
</ejb-jar-ext>

注意:您还需要增加服务器的最大事务超时时间:https://www.ibm.com/support/knowledgecenter/en/SSNGTE_7.1.0/com.ibm.tspm.doc_7.1/install/task/ConfigureTransactionLifetimeTimeout.html

2) 将bean 超时方法更改为不使用事务:

@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)

3) 将 bean 更改为使用 bean 管理的事务,然后要么不使用事务,要么在 UserTransaction 上设置事务超时:

@TransactionManagement(TransactionManagementType.BEAN)
userTransaction.setTransactionTimeout(600);
userTransaction.begin();

4) 配置 EJB TimerService 不重试。计时器方法可能仍会超时,因此技术上会失败,但容器不会重试。不幸的是,这仅适用于非持久性计时器,通过设置 Maximum number of retries 如下所述:https://www.ibm.com/support/knowledgecenter/en/SSAW57_8.5.5/com.ibm.websphere.nd.multiplatform.doc/ae/uejb_timerservice.html