lunes, 26 de agosto de 2013

BEA-001153 using non-transactional AQ backed MDB in Weblogic

I started receiving the following warning in the Weblogic log after changing the transactionality of an AQ backed MDB:

BEA-001153: Forcibly releasing inactive/harvested connection "weblogic.jdbc.wrapper.PoolConnection_oracle_jdbc_driver_T4CConnection@4a8025" back into the data source connection pool "jdbc/XYZ", currently reserved by: java.lang.Exception

The complete stack trace is (BEA-001153):

Forcibly releasing inactive/harvested connection "weblogic.jdbc.wrapper.PoolConnection_oracle_jdbc_driver_T4CConnection@4a8025" back into the data source connection pool "jdbc/XYZ", currently reserved by: java.lang.Exception
        at weblogic.jdbc.common.internal.ConnectionEnv.setup(ConnectionEnv.java:352)
        at weblogic.common.resourcepool.ResourcePoolImpl.reserveResource(ResourcePoolImpl.java:364)
        at weblogic.common.resourcepool.ResourcePoolImpl.reserveResource(ResourcePoolImpl.java:330)
        at weblogic.jdbc.common.internal.ConnectionPool.reserve(ConnectionPool.java:487)
        at weblogic.jdbc.common.internal.ConnectionPool.reserve(ConnectionPool.java:380)
        at weblogic.jdbc.common.internal.ConnectionPoolManager.reserve(ConnectionPoolManager.java:132)
        at weblogic.jdbc.common.internal.RmiDataSource.getPoolConnection(RmiDataSource.java:474)
        at weblogic.jdbc.common.internal.RmiDataSource.getConnectionInternal(RmiDataSource.java:558)
        at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:518)
        at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:511)
        at oracle.jms.AQjmsDBConnMgr.getConnection(AQjmsDBConnMgr.java:566)
        at oracle.jms.AQjmsConnection.setExceptionListener(AQjmsConnection.java:418)
        at weblogic.ejb.container.internal.JMSConnectionPoller.setUpQueueSessions(JMSConnectionPoller.java:1712)
        at weblogic.ejb.container.internal.JMSConnectionPoller.createJMSConnection(JMSConnectionPoller.java:2298)
        at weblogic.ejb.container.internal.JMSConnectionPoller.connect(JMSConnectionPoller.java:808)
        at weblogic.ejb.container.internal.MDConnectionManager.timerExpired(MDConnectionManager.java:177)
        at weblogic.timers.internal.TimerImpl.run(TimerImpl.java:293)
        at weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:545)
        at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
        at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)

Although this is a very well known exception, it is easier to deal with it when you're working with plain JDBC or in scenarios when you have more control of the underlying connection; but in my case, the connection administration code is provided from server managed components (Foreign Server, JMS Module, destination and connection factory, MDB, etc.).

Before start receiving the warnings, the MDB was using container managed transactionality. Now is using the following attributes (non-transactional):

@TransactionManagement(TransactionManagementType.BEAN)
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)

After doing some research ([1], [2]), I found that when a Weblogic MDB has Bean managed or NOT_SUPPORTED transaction type, then two dedicated connections are reserved for that MDB:
Looking at the stack trace, it is reasonable to think the warning corresponds to the "AQ JMS Exception Listener" connection (and not to the polling one). Looking at the documentation, you can see the default ping frequency for the periodical exception listener database ping es 2 minutes (Setting the Ping Period for the Exception Listener). So, this connection is idle during 2 minutes each time.

Casually, in my environment, the underlying JDBC data source (jdbc/XYZ: the one you specify in the datasource JNDI Property of the Foreign Server) had a "Inactive Connection Timeout" value of 60 seconds.

Hence, having these simultaneous settings, has to be the reason the warning is being generated (the underlying data source checks for idle connection more often that the Exception Listener connection gets busy):

Data Source "Inactive Connection Timeout" = 60 (seconds) < MDB Exception Listener connection "ping period" = 120 (seconds)

After increasing the Data Source "Inactive Connection Timeout", the warning stopped appearing.

It would be better to reduce the Exception Listener "ping period" value, but I haven't find a way to do it (neither in the JMS Module, Foreign Server, Destination, Connection Factory or MDB).

References:


No hay comentarios: