我们有4个计时器作业,每天在不同的时间运行。为此,我们使用具有4个线程的内部默认持久计时器调度程序。在此批处理作业中,我们将检索许多DB2表的内容,然后将每个表数据存储在远程服务器或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)
发生这种情况时,批处理作业将继续到下一个表,但是当所有表完成后,它将再次重新启动同一作业。我们想停止重新启动批处理作业。您能帮我们怎么做吗?
答案 0 :(得分:1)
有几种方法可以实现所需的行为:
1)增加Bean的事务超时,以使timer方法成功完成。这是在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