Back Forum Reply New

problem with DataSourceTransactionManager

I met a problem with DataSourceTransactionManager (already resolved, but i don't know why).

I have a simple application use one C3p0 pooled datasource and set its maxSize to 5, and config quot;hibernateSessionFactoryquot;, quot;hibernateTemplatequot; and quot;transactionManagerquot;(using DataSourceTransactionManager). Later in my testcase I created 10 client thread to call my business method(with transaction attribute on it), but they all failed, all transactions hangs on(can't get the database connection), but if client threads' count is less than 5, everything will be ok.

finally I switched my transaction manager to HibernateTransactionManager(everything else keep same), the problem gone.  !!!!confused.

is that DataSourceTransactionManager can only come with direct datasource usage? and must use HibernateTransactionManager with hibernate#65311;

thanks#65281;

is that DataSourceTransactionManager can only come with direct datasource usage? and must use HibernateTransactionManager with hibernate?

You have to use the transactionmanager appropriate for your data access technology. So yes for hibernate that means the HibernateTransactionManager. If you mix hibernate and jdbc it is enough to configure the HibernateTransactionManager because that can also manage jdbc transactions.

thanks!

but why all threads hang on when concurrency is higher than C3p0's maxSize? shouldn't it be some threads can finish work?

No.. Due usage of the  wrong transactionmanager resources aren't freed and thus are kept open and never return to the pool. Even if a thread is already finished the resource is still in use from the perspective of the connection pool.

Hi Marten Deinum, first thanks!

Now I know the problem due to the usage of wrong transactionmanager and the key issue is that the connection resource is not returned to the pool, but what confused me is why those threads who can get the resource(even they don't return it) are also failed to finish transaction, in my testcase ,those threads are the first clients for the pool (no threads access the pool before), but those threads  should have the connection and can do sql execution, but they don't, none of them execute any sql even just quot;select * from .....quot;. from spring's log seems they all blocked after they get the connection.
In my opinion, if my pool size is 5, so there should be 5 threads can finish work, and since they don't release resource so the 6th thread will failed.  I think this is dependent on spring's DatasouceTransaction implementation(I didn't read its code).

Another tricky point is even so my application still performs well(it already keep running for several days..) under low concurrency seems the problem of unrelease resource is not so influential.

If i don't use spring i think there will be no any problem, i can handle the transaction myself, but ...... Spring confused me!!!

^_^

thanks again and sorry for my pool english!

mit();
} catch (SQLException e) { // do what?
} finally { try {  connection.close } catch (SQLException e) {}
}
The same basically goes for hibernate.

Now I know the problem due to the usage of wrong transactionmanager and the key issue is that the connection resource is not returned to the pool, but what confused me is why those threads who can get the resource(even they don't return it) are also failed to finish transaction, in my testcase ,those threads are the first clients for the pool (no threads access the pool before), but those threads should have the connection and can do sql execution, but they don't, none of them execute any sql even just quot;select * from .....quot;. from spring's log seems they all blocked after they get the connection.

Because if something is transactional a hibernate session is already opened and thus a connection is used. Now if you are going to access a connection yourself/retrieving it yourself there is no connection free anymore.

After checked spring's code I got the reason. Because i use DatasourceTransactionManager, it will get one connection from pool when transaction start, later when thread execute hibernate query, in hibernate session it will get another connection again from pool, since hibernate don't know the connection opened by spring, so  my poor pool... ^_^

BTW the means for managing transaction myself is creating some transaction interceptor like spring for opening hibernate session when transaction start and close when submit(just example), after all i know how to control transaction in hibernate environment but not so familiar with spring's code.

thanks again!
¥
Back Forum Reply New