在运行于Websphere应用程序服务器8.5.5上的EAR应用程序中,我们必须执行CallableStatement(Oracle DB中的调用存储过程),该过程要运行五分钟或更长时间,具体取决于输入数据。由于事务超时(代码WTRN0006W),该操作会自动回滚,该超时在Websphere AS中默认设置为120秒。由于客户要求,我们无法更改此值。
我们可以将输入数据拆分为较小的块,并多次执行CallableStatement以缩短运行时间(约30秒)。处理整个数据块仍然需要超过120秒(如预期)。但是事务超时仍然发生,尽管对于小块(循环)执行的每个语句,我们都是从WAS中配置的数据源获取连接,在语句执行完成提交并关闭连接后,将autocommit设置为false。然后在下一个循环周期再次使用下一个块。
语句执行的整个过程是在无状态EJB中完成的,该状态从计划每天运行两次的Singleton EJB中调用。我们既没有使用JTA也没有使用JPA,只是使用JDBC。
如果我们多次执行语句,是否可以避免事务超时?
在应用程序启动期间我们如何获取数据源:
javax.naming.Context ctx = new InitialContext();
javax.sql.Datasource ds = (javax.sql.Datasource) ctx.lookup("jndi/datasource1");
我们如何获得连接:
java.sql.Connection conn = m24sb.getConnection();
conn.setAutoCommit(false)
我们如何执行语句:
try (CallableStatement sta = conn.prepareCall("{ call SOME_STORED_PROC }"))) {
// ... setting statement params
sta.execute();
// ... resolving returned values
}
然后提交并关闭连接。
提前感谢您的回答!
答案 0 :(得分:2)
尝试将无状态会话bean方法标记为事务NOT_SUPPORTED或NEVER,这将导致它在全局事务之外运行。 (请注意,无论如何,您都需要执行此操作才能使connection.commit()调用有效-由于超时,它可能并没有达到那么远)。
@javax.ejb.TransactionAttribute(javax.ejb.TransactionAttributeType.NEVER)
public void yourStatelessEJBMethod() {
... code that invokes stored procedure and commits transaction
}