2

I have a situation where I need to setup a Proxy of a Pooled DataSource, my code is as follows:

<bean id="dataSourceBean" class="com.mchange.v2.c3p0.ComboPooledDataSource" 
    destroy-method="close">
  <property name="driverClass" value="${jdbc.driverClassName}"/>
  <property name="jdbcUrl" value="${jdbc.url}"/>
  <property name="properties">
    <props>
        <prop key="c3p0.minPoolSize">0</prop>
        <prop key="hc3p0.maxPoolSize">100</prop>
        <prop key="hc3p0.timeout">60000</prop>
        <prop key="c3p0.acquire_increment">10</prop>
        <prop key="c3p0.max_statement">50</prop>
        <prop key="user">${jdbc.username}</prop>
        <prop key="password">${jdbc.password}</prop>
    </props>
  </property>
</bean>

<bean id="dataSourceLockAdvice" 
    class="com.ndot2.datasource.DataSourceLockAdvice"/>

<bean id="dataSource" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target" ref="dataSourceBean"/>

    <property name="interceptorNames">
        <list>
            <value>dataSourceLockAdvice</value>
        </list>
    </property>
</bean>

The problem that I'm having is that the connections aren't being closed anymore and it would seem that the destroy method of the proxied Datasource is no longer being called...

How would I call the Close method of the Proxied Bean? Or should I be implementing the Advice differently?

I've tried searching the Internet but I can't seem to find the answer to this, Help much appreciated!

EDIT:

As requested, here is my transaction management declarations (I'm using Appfuse)

<aop:config>
    <aop:advisor id="userManagerTx" advice-ref="userManagerTxAdvice" pointcut="execution(* *..service.UserManager.*(..))" order="0"/>
    <aop:advisor id="userManagerSecurity" advice-ref="userSecurityAdvice" pointcut="execution(* *..service.UserManager.saveUser(..))" order="1"/>
    <aop:advisor id="managerTx" advice-ref="txAdvice" pointcut="execution(* *..service.*Manager.*(..))" order="2"/>
</aop:config>

<!-- Enable @Transactional support -->
<tx:annotation-driven/>

<!-- Enable @AspectJ support -->
<aop:aspectj-autoproxy/>

<!-- Activates scanning of @Autowired -->
<context:annotation-config/>

<!-- Activates scanning of @Service -->
<context:component-scan base-package="com.ndot2.service"/>

<tx:advice id="txAdvice">
    <tx:attributes>
        <!-- Read-only commented out to make things easier for end-users -->
        <!-- http://issues.appfuse.org/browse/APF-556 -->
        <!--tx:method name="get*" read-only="true"/-->
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>

<tx:advice id="userManagerTxAdvice">
    <tx:attributes>
        <tx:method name="save*" rollback-for="UserExistsException"/>
    </tx:attributes>
</tx:advice>

<bean id="userSecurityAdvice" class="com.ndot2.service.UserSecurityAdvice"/>

I don't have any @Transactional or @AspectJ driven Transaction management...

Brian
  • 402
  • 3
  • 12
  • what do you mean by closed connections? destroy method is executed on the application shutdown, i don't think that it's connected with connection leaks anyhow, are sure that the leaks occur on the app shutdown? – Boris Treukhov Nov 15 '12 at 04:34
  • You're quite right, the leaks aren't happening on shutdown – Brian Nov 15 '12 at 07:33
  • what is your transaction manager declaration, do you use tx annotation driven with @transactional? – Boris Treukhov Nov 15 '12 at 10:07
  • Hi Boris, I have included my transaction management config in the original question. Thanks for your help! – Brian Nov 15 '12 at 16:54
  • 1
    I think that the first step to do is to try to localize the place where the leaks occur, take a look http://stackoverflow.com/questions/4104125/how-to-monitor-c3p0-connections I believe it allows to watch leaks in real time - so you can check if the leak occurs during execution of some specific service call(does it occur for example in the nested transaction blocks of UserManager?). – Boris Treukhov Nov 15 '12 at 19:35
  • @BorisTreukhov thanks for your help, if you add this as an answer I will accept it. – Brian Nov 16 '12 at 09:14
  • To be honest, I ended up just advising the hibernate Dao's instead, as it accomplished the same thing in my application since everything goes through them anyway! – Brian Nov 16 '12 at 18:02
  • Do you access the db via sf.getCurrentSession() or via HibernateTemplate? maybe your services are created in the servlet context instead of web app root context. I remember I could not get getCurrentSession approach to work without leaks but the error mysteriously disappeared when I became more proficient in Spring :-/. – Boris Treukhov Nov 16 '12 at 18:07
  • there are no leaks normally... only when I put the advice on the dataSource... – Brian Nov 16 '12 at 18:20

1 Answers1

0

If you have the connection leaks in your application, the first step to do is to try to localize the place where the leaks occur, using the appropriate monitoring tools. As for c3p0, I believe it provides connection monitoring via JMX, as it's discussed in the related question.

So you can check with the debugging and monitoring tools if the leak occurs during some specific service call.

Then you should watch for different peculiarities: for example, in your configuration UserManager has more than one transaction advice, which could be the cause. In Spring container with annotated configuration a common error is that the bean in not being wrapped by transaction proxy, because the annotated transaction management is configured for the different IoC container. Another possible cause is that your method tries to manage transactions manually, and don't succeed in doing this correctly.

Community
  • 1
  • 1
Boris Treukhov
  • 17,493
  • 9
  • 70
  • 91