Spring IntTest is getting "Failed to grow the connection pool" from Atomikos - spring

I have a Spring application that normally runs fine in WebLogic.
I have a set of integration tests that use the Atomikos "Transaction Essentials" framework to provide the standalone transaction manager. I had this working, but I'm now seeing a new problem, but I don't know what I might have changed that would make this happen.
I'm seeing a stack trace beginning like this:
org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is com.atomikos.jdbc.AtomikosSQLException: Failed to grow the connection pool
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80)
Here are the relevant bean definitions:
<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init" destroy-method="close">
<!-- when close is called, should we force transactions to terminate or not? -->
<property name="forceShutdown">
<value>true</value>
</property>
</bean>
<!-- Also use Atomikos UserTransactionImp, needed to configure Spring -->
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout">
<value>300</value>
</property>
</bean>
<!-- Configure the Spring framework to use JTA transactions from Atomikos -->
<bean id="catalogTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager">
<ref bean="atomikosTransactionManager" />
</property>
<property name="userTransaction">
<ref bean="atomikosUserTransaction" />
</property>
</bean>
I also have several like this:
<bean id="appConfigDataSource"
class="com.atomikos.jdbc.AtomikosDataSourceBean"
p:uniqueResourceName="appConfigDataSource"
p:xaDataSourceClassName="oracle.jdbc.xa.client.OracleXADataSource"
p:poolSize="5">
<property name="xaProperties">
<props>
<prop key="user">${ds.appconfig.userName}</prop>
<prop key="password">${ds.appconfig.password}</prop>
<prop key="URL">${ds.appconfig.url}</prop>
</props>
</property>
</bean>
I tried changing the "5" to "50". This makes it run longer, but it still fails with the same error. There's no way that it would even need 5 or even 50 connections. I have a strong feeling that if I changed it to a larger number, it would run even longer, and still fail with the same error.
What might I be missing?

Never mind. It was a simple problem. I forgot that the hostname of my test database changed a while ago, and I forgot to change the property value.

Related

HikariCP Lazy with Spring LazyConnectionDataSourceProxy

Can a HikariCP Datasource be started with a Lazy configuration?
For that, i'm using Spring LazyConnectionDataSourceProxy.
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig" lazy-init="true">
<property name="poolName" value="TargetHikariCP" />
<property name="dataSourceClassName" value="oracle.jdbc.pool.OracleDataSource" />
<property name="connectionInitSql" value="SELECT 1 FROM DUAL"/>
<property name="leakDetectionThreshold" value="300000"/>
<property name="minimumIdle" value="1"/>
<property name="maximumPoolSize" value="10"/>
<property name="autoCommit" value="false"/>
<property name="dataSourceProperties"> <props> ... </props> </property>
</bean>
<bean id="dataSourceLazy" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close" lazy-init="true">
<constructor-arg ref="hikariConfig" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
<property name="targetDataSource" ref="dataSourceLazy" />
</bean>
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager" lazy-init="true">
<property name="dataSource" ref="dataSource" />
</bean>
Nevertheless, its not working, as the Datasource is started on project startup.
The same configuration, when using a org.springframework.jdbc.datasource.DriverManagerDataSource, works correctly.
In the version > 3 we can set setInitializationFailTimeout(-1);
According to docs:
Any value greater than zero will be treated as a timeout for pool initialization.The calling thread will be blocked from continuing until a successful connection
to the database, or until the timeout is reached. If the timeout is reached, then
a PoolInitializationException will be thrown.
A value of zero will not prevent the pool from starting in the
case that a connection cannot be obtained. However, upon start the pool will
attempt to obtain a connection and validate that the connectionTestQuery
and connectionInitSql are valid. If those validations fail, an exception
will be thrown. If a connection cannot be obtained, the validation is skipped
and the the pool will start and continue to try to obtain connections in the
background. This can mean that callers to DataSource#getConnection() may
encounter exceptions.
A value less than zero will bypass any connection attempt and validation during
startup, and therefore the pool will start immediately. The pool will continue to
try to obtain connections in the background. This can mean that callers to
DataSource#getConnection() may encounter exceptions.
HikariCP has a property, initializationFailFast, that controls whether the pool will "fail fast" if the pool cannot be seeded with initial connections successfully:
This property controls whether the pool will "fail fast" if the pool cannot be seeded with initial connections successfully. If you want your application to start even when the database is down/unavailable, set this property to false. Default: true
This property was documented in their site, but per version 2.6.2 its not, but it seems its still supported.
In my use case, the use of this property should be enough to solve my problem.

Hibernate Envers not Finding JPA Transaction:

I've been trying to wrap my head around this issue all day.
Currently our project has setup JPATransactionManager through a Spring Application Context to take care of our various session transactions with the use of #Transactional on all services that take care of persistence and deletions (DAO usage).
Changing over from Hibernate 3 to 5, we wanted to remove our use of a custom audit interceptor and move onto using Hibernate Envers. I have annotated all my classes properly and have the tables being created, but once it actually gets to a point of insertion, the listener throws an error in which it can't find the current transaction given by JPA:
org.hibernate.envers.exception.AuditException: Unable to create revision because of non-active transaction
at org.hibernate.envers.event.spi.BaseEnversEventListener.checkIfTransactionInProgress(BaseEnversEventListener.java:132)
at org.hibernate.envers.event.spi.EnversPostInsertEventListenerImpl.onPostInsert(EnversPostInsertEventListenerImpl.java:34)
at org.hibernate.action.internal.EntityIdentityInsertAction.postInsert(EntityIdentityInsertAction.java:156)
at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:102)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:597)
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:232)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:213)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:256)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:318)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:275)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:113)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:97)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:651)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:643)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:638)
Looking inside the code, it seems that it's basing the transaction status off it's default value of INACTIVE meaning that it's not hooking into the transaction properly. I know that Hibernate Envers also automatically pushes the listeners into hibernate with recent versions so I don't know if this may also be a source of the issue.
I know that its been documented to work with HibernateTransactionManager but we wish to step away from using that in favor of hooking up our transactions and sessions solely via Spring making things easier so it may also be the need of finding an alternative to envers. Does anyone have any advice or solutions to this problem? Or also hit this issue?
ApplicationContext.xml
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="dataSource" ref=“dataSource" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="net.sourceforge.jtds.jdbcx.JtdsDataSource" />
<property name="url" value="jdbc:jtds:sqlserver://.." />
<property name="username" value=“..." />
<property name="password" value=“..." />
</bean>
<bean id="hibernateProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location">
<value>classpath:hibernate.properties</value>
</property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="hibernateProperties">
<ref bean="hibernateProperties" />
</property>
</bean>
<bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="transactionAttributes">
<props>
<prop key="find*">PROPAGATION_SUPPORTS,readOnly
</prop>
<prop key="load*">PROPAGATION_SUPPORTS,readOnly
</prop>
<prop key="make*">PROPAGATION_REQUIRED</prop>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="refresh">PROPAGATION_SUPPORTS</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_SUPPORTS,readOnly
</prop>
</props>
</property>
</bean>
<bean id="PROPAGATION_REQUIRED" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
<property name="transactionManager" ref="transactionManager" />
</bean>
hibernate.properties
#hibernate.hbm2ddl.auto=update
hibernate.show_sql=true
hibernate.connection.datasource=java\:comp/env/datasource
#hibernate.connection.provider_class=org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl
hibernate.connection.provider_class=org.hibernate.connection.DatasourceConnectionProvider
hibernate.cache.use_second_level_cache=true
hibernate.cache.use_query_cache=true
#hibernate.generate_statistics=true
hibernate.cache.use_structured_entries=true
hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
hibernate.id.new_generator_mappings=false
hibernate.dialect=org.hibernate.dialect.SQLServer2008Dialect
hibernate.listeners.envers.autoRegister=false
org.hibernate.envers.track_entities_changed_in_revision=false
org.hibernate.envers.audit_table_prefix=AUD_
org.hibernate.envers.audit_table_suffix=
My DAOs are hooked up using the txProxyTemplate like so
<bean id="objectDAO" parent="txProxyTemplate">
<property name="target">
<bean
class="path.to.objectDAOImpl">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
</property>
</bean>
All my services that use the various DAOs are simply hooked up using the #Transactional annotation where we want to have transactions. I've been able to see through trace that my transactions are succeeding in completing and rolling back as well when there are errors. Once I added envers into the mix, the auditing can't find the transaction to join. There must be something I'm missing but I'm not sure what it is.
I don't believe you need to define a txProxyTemplate bean nor a SpringTransactionPolicy from my experience. This functionality has since been superseded with the <tx:/> tags and the use of the #Transactional annotation.
You just need to make sure a JpaTransactionManager has been created and associated as the transactionManager associated with the <tx:annotation-driven/> tag.

Spring MVC refresh database beans in application context

I am developping a Spring MVC web application that use the dbcp database connection pool.
<bean id="datasourceAR_XXX" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" scope="singleton">
<property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property>
<property name="url"><value>jdbc:oracle:thin:#XXX.XXX.com:1500:SERVICE</value></property>
<property name="maxActive"><value>100</value></property>
<property name="maxIdle"><value>10</value></property>
<property name="username"><value>XXX</value></property>
<property name="password"><value>XXX</value></property>
</bean>
I recently moved the scope of those beans to singleton because the amount of connection per session started to be a bit too much.
The problem is :
Our database is shutting down every sunday and the spring application seems to act strangely by keeping the socket open and does not refresh the connection as I thought it would do.
Is there a way to refresh the beans scoped as singleton in a way that will refresh the connection everyday and not be obliged to relaunch the application every monday?
What you want to do is to configure validation for your connections. When a connection is borrowed from the pool you want to make sure that that connection is valid. For this you can specify the validationQuery property on your datasource.
<bean id="datasourceAR_XXX" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" scope="singleton">
<property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property>
<property name="url"><value>jdbc:oracle:thin:#XXX.XXX.com:1500:SERVICE</value></property>
<property name="maxActive"><value>100</value></property>
<property name="maxIdle"><value>10</value></property>
<property name="username"><value>XXX</value></property>
<property name="password"><value>XXX</value></property>
<property name="validationQuery" value="select 1 from dual" />
</bean>
See DBCP - validationQuery for different Databases for a list of possible validation queries for different databases.
There are some issues with Commons DBCP and it is pretty old (although there is a DBCP 2.x now). I would suggest moving to a different datasource like HikariCP this datasource is also a JDBC 4.x based datasource which allows for easier connection validation (it is part of the JDBC 4 spec).
<bean id="datasourceAR_XXX" class="com.zaxxer.hikari.HikariDataSource">
<property name="datasourceClassName" value="oracle.jdbc.pool.OracleDataSource"/>
<property name="maximumPoolSize" value="20" />
<property name="username" value="XXX" />
<property name="password" value="XXX" />
<property name="datasourceProperties">
<props>
<prop key="serverName">XXX.XXX.com</prop>
<prop key="port">1500</prop>
<prop key="databaseName">SERVICE</prop>
</props>
</property>
</bean>
If your oracle driver is new enough you don't need a validation query anymore as validation is provided by the driver instead of needing to be done with a query. Next to that you probably have better results with this pool.
Also you might have a bit of a large pool size, nice article/presentation about pool sizing can be found here.

Forcing hibernate to release connection on session Spring MVC

I am using Spring MVC 3 and Hibernate 3.6, I use xml configured transaction management,
my code works greate but my JDBC are not being released although it says it does.
I checked it with JProfiler and it says the connection is open.
this is my spring-config code
<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/parse_web?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root" />
<property name="password" value="miles106" />
<property name="initialSize" value="5"/>
<property name="maxActive" value="50000"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="ds" />
<property name="mappingResources">
<list>
<value>com/mubasher/parsewebpage/entities/Changes.hbm.xml</value>
<value>com/mubasher/parsewebpage/entities/Owners.hbm.xml</value>
<value>com/mubasher/parsewebpage/entities/Ownerships.hbm.xml</value>
<value>com/mubasher/parsewebpage/entities/TargetCompanies.hbm.xml</value>
<value>com/mubasher/parsewebpage/entities/TempData.hbm.xml</value>
<value>com/mubasher/parsewebpage/entities/Exceptions.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.connection.useUnicode">true</prop>
<prop key="hibernate.connection.characterEncoding">UTF-8</prop>
<prop key="hibernate.connection.charSet">UTF-8</prop>
<prop key="hibernate.connection.release_mode">after_statement</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
and this is my debug code
DEBUG [myExec-2] (JDBCTransaction.java:223) - re-enabling autocommit
DEBUG [myExec-2] (JDBCTransaction.java:143) - committed JDBC Connection
DEBUG [myExec-2] (ConnectionManager.java:427) - aggressively releasing JDBC connection
DEBUG [myExec-2] (ConnectionManager.java:464) - releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
DEBUG [myExec-2] (HibernateTransactionManager.java:734) - Closing Hibernate Session [org.hibernate.impl.SessionImpl#52ab7af2] after transaction
DEBUG [myExec-2] (SessionFactoryUtils.java:789) - Closing Hibernate Session
but in JProfiler i can see that the connection is still open as you see
this is realy causing me problems, my application is doing massive database work, so I need the connection to close as soon as the work is done, should I use maxIdle ?
Connections are not closed, they are reused. This is the whole purpose of commons-dbcp, which stands for Database Connection Pool.
Establishing a new connection is usually an expensive operation. So what DBCP is doing is that instead of closing connection, it leaves it open and returns it to the connection pool for another use.
If you want your database connections to get closed and re-opened with each request, then you need to use a different data source (e.g. org.springframework.jdbc.datasource.SimpleDriverDataSource).
UPDATE 1: Also note, that in your example you are setting maximum number of parallel connections (maxActive) to be 50000. That is some extreme number (default is 8!!!), which IMO can cause a lot of problems.
UPDATE 2: Using maxIdle is a good idea if you don't wan't to get rid of the pool. But that will not save you from "having non-closed connections". If you are thinking about setting maxIdle=0, then drop the pool completely.
UPDAET 3: I just need to stress out this one again - If you need 50000 parallel connections, then there is really something wrong with your code.

Nested Spring TxProxyTemplate issue

I have the following config.
<bean id="abcManager" parent="TxProxyTemplate">
<property name="target">
<bean class="com.x.y.AbcManagerImpl">
<property name="abcDAO" ref="abcDAO"/>
<property name="xyzManager" ref="xyzManager"/>
</bean>
</property>
</bean>
<bean id="xyzManager" parent="TxProxyTemplate">
<property name="target">
<bean class="com.x.y.XyzManagerImpl">
<property name="abcDAO" ref="abcDAO"/>
<property name="anotherManager" ref="anotherManager"/>
</bean>
</property>
</bean>
<bean id="anotherManager" parent="TxProxyTemplate">
<property name="target">
<bean class="com.x.y.AnotherManagerImpl">
<property name="abcDAO" ref="abcDAO"/>
<property name="oneMoreManager" ref="oneMoreManager"/>
</bean>
</property>
</bean>
What is the issue with the following configuration? will having the same DAO at the different levels cause concurency issues?
We found that we get lots of weblogic connection releases when we have high load.
How is this related to the connection release issue?
We use Hibernate for DAO operations.
First, analyse the logs to see when spring creates and closes transactions.
Set the logger for org.springframework.transaction to DEBUG for this.
Next my guess is you need to examine your #Transactional annotations (which I assume you use on your managers (=services?). Make sure the propagation is set correctly because this might be related to your issue (hard to say without seeing your manager's code of course).
To answer your question directly:
What is the issue with the following configuration? will having the same DAO at the different levels cause concurency issues?
Nothing, and no. I don't see anything wrong with this. Not sure what you mean about 'same DAO' - you don't have the same DAO. You have the same parent, but 3 distinct DAOs.
If you're asking, then, why is weblogic closing your DB connections before your transaction completes, we wouldn't be able to answer that with the information above.

Resources