Connection pool problem with Spring and programmatic transaction management - java

I need your help in order to solve connection pool problem with Spring.
I’m using Spring with Java 1.4 (no annotation).
Here is the datasource and the connection pool definition:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName">
<value>${database.jdbcName}</value>
</property>
<property name="url" value="jdbc:sybase:${database.url}">
</property>
<property name="username">
<value>${database.username}</value>
</property>
<property name="password">
<value>${database.password}</value>
</property>
<property name="maxActive">
<value>${database.maxActive}</value>
</property>
<property name="maxIdle" >
<value>${database.maxIdle}</value>
</property>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.SybaseDialect</prop>
<prop key="show_sql">true</prop>
<prop key="hibernate.connection.release_mode">after_transaction</prop>
<prop key="hibernate.dbcp.maxWait">100000</prop>
<prop key="hibernate.connection.autocommit">false</prop>
<prop key="cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
</props>
</property>
...
When all the connections are active, if the system need a new connection I got a message saying “opening JDBC connection” and all the process are stopped. I don’t understand why all the threads are locked.
All services and DAO classes are defined as singletons in Spring application context.
Any idea?
Thanks for your help.
Béranger

What values are you using for maxActive and maxIdle? I can give you a more definitive answer if I know those values, but in the meantime you can also try changing the value of hibernate.dbcp.maxWait from 100000 to 1 and test your application again.
Also make sure you haven't you accidentally made some of your DAO methods synchronized.

This was a weird one but I finally solved my problem.
The reason of this connection locking was that I used both declarative and programmatic transaction management with Spring. I think that my programmatic transaction management was wrong.
Here is the code used to begin a transaction:
//Return Spring context
ApplicationContext context = ApplicationContextHolder.getContext();
// transactionManager
PlatformTransactionManager transactionManager = (PlatformTransactionManager) context.getBean("txManager");
//Set propagation required
DefaultTransactionDefinition td = new DefaultTransactionDefinition();
td.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
// Begin
TransactionStatus transactionStatus = transactionManager.getTransaction(td);
As you can see I set the programmatic transactions as “required”. But when those transactions were started in a transactional context, Spring didn’t recognized the current transaction and started a new one. It leaded to a connection locking...
I solved this mystery by removing the programmatic transaction management.

Related

OpenEntityManagerInViewInterceptor- No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call

We are migrating from Spring 3 to Spring 4 along with introducing EntityManager. Earlier in the code we had used OpenSessionInViewInterceptor as interceptor in the bean with urlmapping. It was working fine by attaching a session to every thread request from web.
Now I am using OpenEntityManagerInViewInterceptor but the EntityManager is not attached to the current thread, and get the exception
No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call
If I put #Transactional above my DAO method then it works fine, but I will have to do it in lot of places, so want to avoid it and trying to fix it with OpenEntityManagerInViewInterceptor. Please let me know how can I get it working.
applicationContext.xml -
<bean id="openEntityManagerInViewInterceptor" class="org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
dispatcher-servlet.xml -
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/EditHelp/*.do">EditHelpController</prop>
</props>
</property>
<property name="interceptors">
<list>
<ref bean="openEntityManagerInViewInterceptor" />
</list>
</property>
</bean>
Any help would be appreciated. Thank you.

HSQL file based database from script

I have a question. I was playing around with JSF/ Spring/ Hibernate and HSQL.
I have a small test application for this purpose and for one feature I wanted to implement I needed a possiblity to persist some data. I didn't wanted to have a full fledged database, so I choose HSQL. Starting from this tutorial (http://devcrumb.com/hibernate/hibernate-jpa-spring-and-hsqldb) I build my application. I had some problems with datatypes and I have chosen to build my database from a script.
Like in the tuorial I had defined my datasource like this in my application.xml, except that I had changed the url property to use a file.
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>org.hsqldb.jdbcDriver</value>
</property>
<property name="url">
<value>jdbc:hsqldb:hsql://localhost/testdb</value>
</property>
<property name="username">
<value>sa</value>
</property>
<property name="password">
<value></value>
</property>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="jpaData" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
Now, I have changed the datasource to something like this:
<jdbc:embedded-database id="dataSource" type="HSQL">
<jdbc:script location="classpath:embeddedDbStructure.sql" />
</jdbc:embedded-database>
Everything works fine so far.
My problem is, that this database is deleted when the server is shut down. Is there a possibility to use both? A script as base for the structure of my database but the db itself is written to a file on my filesystem so that it is available after a server restart? I know there are propably a few solutions to achieve this via some code, but is there a possibility to configure it that way?
Thanks in advance
Actually for your case, you are using the hsqldb in-memory mode, the spring is house a inmemory database indeed. To reuse the file database you need to update the hsqldb mode to use the "In-Process Mode" like "jdbc:hsqldb:file:testdb"
And a sample question is Embedded HSQLDB persist data to a file, you can refer to this.

Spring app should start even though DB is down

I have a spring app which do minimal operations with DB.
And I have a requirment that my application should run under the absence of DB(or when db is down).Below is my datasource configuration.
<bean id="dt31DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close" depends-on="systemPropertyInitializer"
p:driverClass="${dt31.driver_class}"
p:jdbcUrl="${dt31.url}"
p:user="${dt31.username}"
p:password="${dt31.password}"
p:idleConnectionTestPeriod="1000"
p:maxPoolSize="4"
p:minPoolSize="2"
p:maxIdleTime="2000"
p:unreturnedConnectionTimeout="600"
p:contextClassLoaderSource="library"
p:privilegeSpawnedThreads="true"
p:initialize=false
/>
<bean id="dt31SessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dt31DataSource"/>
<property name="packagesToScan" value="com.t22.dt31"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
${dt31.dialect}
</prop>
<prop key="hibernate.show_sql">
false
</prop>
<prop key="hibernate.hbm2ddl.auto">
update
</prop>
</props>
</property>
</bean>
I found a page in google,saying to use "initialize: false" in spring data source configuration.But I am using "ComboPooledDataSource" datasource which does not have this property.Is there any other way to achieve this ?
The application service layer can operate with two DAO layers (file system and database), so when the DB is down you catch the connection acquire exception and switch to the file system instead.
Having two sources of truth is going to make it difficult to preserve consistency across two different data sources, especially if one resource is not available.
When both resources are available you can use XADisk and Bitronix for XADataSource and JTA transaction management.

How to handle max database connections with Hibernate?

Below is Hibernate configuration from Hibernate.xml
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.c3p0.timeout">300</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
.....
</list>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Below is code from GenricDaoImpl class (code 1)
#Override
public T save(T t) {
Session session = getSessionFactory().openSession();
Transaction tx=session.beginTransaction();
session.saveOrUpdate(t);
tx.commit();
session.close();
return t;
}
and other code from project (code 2)
Query executeQuery = getSession().createQuery(hql);
UserProfileuser = (UserProfile) executeQuery.uniqueResult();
Above both codes I am using in project. My question is which coding need to follow ? code 1 or code 2 to avoid max connections error.? I can connect max 1000 connections with database. But in some cases it is going more than 1000 . So i want to maintain database connection minimum.
Please guide me.
Using 1000 database connections doesn't sound like a very good idea. Each extra database connection requires extra RAM and increases the likelihood of concurrency issues (deadlocks).
Since you use C3P0 you should have a max connection size:
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>
If you run out of connections then it may be because:
you don't close the Hibernate Session, and the associated JDBC connection doesn't get released to the pool
your queries take too long to execute and so they don't release connections fast enough
I recommend using a connection pool size utility, such as FlexyPool to understand better the database connection usage patterns.
Regarding the two choices:
The 1st example contradicts the automatic session management support offered by Spring. When you use Spring you should not manage Hibernate Sessions yourself. You should let the transaction manager call the appropriate Hibernate initializing callbacks on a new transaction boundary.
In your example, if the session throws an exception, the session will not be closed and the connection might be dangling around. That's because you haven't used a try/finally block for releasing the Session.
The 2nd example is better, but you need to wrap it into a #Transactional service.

Spring 3 and hibernate 4.X facing a transaction Manager Exception in destroy-method

We are currently using Spring 3 with hibernate 4.4 in our project.
A snippet of my database config xml looks as follows
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass">
<value>${jdbc.driver.className}</value>
</property>
<property name="jdbcUrl">
<value>${jdbc.url}</value>
</property>
<property name="user">
<value>${jdbc.username}</value>
</property>
<property name="password">
<value>${jdbc.password}</value>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.hibernate.dialect}</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.jdbc.batch_size">20</prop>
<prop key="hibernate.current_session_context_class">managed</prop>
</props>
</property>
<property name="packagesToScan" value="com.sample.entity" />
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<tx:annotation-driven />
While we were testing our war , we came across this exception .
13:27:19,511 ERROR TransactionInterceptor:419 - Application exception overridden by rollback exception
org.springframework.beans.factory.BeanCreationNotAllowedException:
Error creating bean with name 'transactionManager': Singleton bean creation not allowed
while the singletons of this factory are in destruction (Do not request a bean from a
BeanFactory in a destroy method implementation!)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:212)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager(TransactionAspectSupport.java:248)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:100)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
I am unable to figure out if this is because of the destroy-method =close mentioned in the config file . I am also using the #Transactional annotation at both the Service layer and the database layer . Will this cause any issue?
We were trying to test a scenario where in multiple people (around 150) are all trying to access our application at the same time.
Kindly help me out.. Please do let me know, If more details are needed.
Thanks
As the spring doc says in Section 3.6.1.5
The order of startup and shutdown invocations can be important. If a "depends-on" relationship exists between any two objects, the dependent side will start after its dependency, and it will stop before its dependency. However, at times the direct dependencies are unknown. You may only know that objects of a certain type should start prior to objects of another type. In those cases, the SmartLifecycle interface defines another option, namely the getPhase() method as defined on its super-interface, Phased.
So you need the bean to implement the SmartLifeCycle, Javadoc for SmartLifeCycle Interface 1: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-factory-lifecycle-processor.
Hope this helps !!

Categories