2

我有一种情况需要设置池数据源的代理,我的代码如下:

<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>

我遇到的问题是连接不再被关闭,并且似乎不再调用代理数据源的destroy方法......

我将如何调用代理 Bean 的 Close 方法?还是我应该以不同的方式实施建议?

我已经尝试在互联网上搜索,但我似乎无法找到答案,非常感谢帮助!

编辑:

根据要求,这是我的事务管理声明(我正在使用 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"/>

我没有任何@Transactional 或@AspectJ 驱动的事务管理...

4

1 回答 1

0

如果您的应用程序中存在连接泄漏,第一步是尝试使用适当的监控工具定位发生泄漏的位置。至于 c3p0,我相信它通过 JMX 提供连接监控,正如相关问题中所讨论的那样。

因此,如果在某些特定的服务调用期间发生泄漏,您可以使用调试和监控工具进行检查。

然后你应该注意不同的特性:例如,在你的配置中 UserManager 有多个事务建议,这可能是原因。在带有注解配置的 Spring 容器中,一个常见的错误是 bean 没有被事务代理包装,因为注解事务管理是为不同的 IoC 容器配置的。另一个可能的原因是您的方法尝试手动管理事务,但未能正确执行此操作。

于 2012-11-16T11:46:52.330 回答