WebLogic下EJB Timer异常:定时器未触发及数据库连接问题
WebLogic下@Singleton中EJB调度器异常问题分析
1. 第一个定时器完全不触发的可能原因
- Singleton锁阻塞:
@Singleton默认使用@Lock(LockType.WRITE),同一时间仅能有一个方法执行。如果第二个定时器的任务长时间占用锁(比如因数据库连接问题卡住),第一个定时器会持续等待锁资源,表现为无日志、不触发。 - 初始化静默失败:部署Singleton时若遇到依赖资源未就绪(如JNDI lookup失败、数据库连接池未初始化完成),可能导致第一个定时器的注册逻辑被静默跳过,仅在特定部署场景出现,重启后资源就绪则恢复正常。
- 调度线程池耗尽:若服务器上存在大量阻塞性定时任务,WebLogic调度器线程池被占满,第一个定时器的触发请求无法分配到线程,就会出现无执行、无日志的情况。
2. 第二个定时器抛出「连接已关闭」SQLException的原因
- 连接池存在失效连接:WebLogic连接池的
Inactive Connection Timeout或Test Connections On Reserve配置不合理,导致池中留存了数据库端已关闭的无效连接。定时器获取到这类连接时执行getOnlinePaymentInfo.fortimer.creatDebit查询,就会触发连接关闭异常——直接在数据库执行正常是因为用了新建立的有效连接,和池内失效连接无关。 - 事务超时强制回收连接:如果定时器任务执行时间超过WebLogic配置的
Transaction Timeout,容器会强制回滚事务并回收连接,此时任务若仍在执行数据库操作,就会抛出该异常。 - 事务上下文冲突:
@Singleton方法默认继承容器事务,若第一个定时器的事务未正确提交/回滚,可能导致连接被异常占用,第二个定时器获取的连接处于无效状态。
3. WebLogic会因多次执行失败停止调度器吗?
默认情况下,WebLogic的EJB定时器不会因多次执行失败停止调度,它会按配置周期持续重试。但存在两种例外:
- 若任务抛出
javax.ejb.EJBException且包含javax.ejb.NoSuchObjectLocalException,容器会判定定时器关联的EJB实例已失效,进而取消该定时器。 - 若通过WebLogic控制台或
weblogic-ejb-jar.xml配置了max-retry-attempts等自定义重试参数,达到重试上限后会停止调度。
内容的提问来源于stack exchange,提问作者Reza
相关产品推荐
相关产品推荐

