【问题标题】:using tomcat datasource - how to access datasource to get current db pool status by spring jndi使用tomcat数据源-如何通过spring jndi访问数据源以获取当前的数据库池状态
【发布时间】:2017-07-20 02:00:48
【问题描述】:

现状

我在 web 和 rest api 服务器上使用 Jmeter 进行压力负载测试,但是一些事务的响应时间延迟了很多,所以我使用 Spring Aspect 来获取方法处理时间。我无法设置的是某些过程调用需要太多时间,因此尝试通过使用特定事务写入日志来检查 DB 进程时间(获取 con、释放 con、纯 db 进程时间)。 JMX 不是一个选项,因为我无法使用它跟踪事务。我只想将 ThreadContext 标记为打开的 DB 池状态,以便我可以同时检查慢事务和 DB 池状态。

这里不考虑使用来自 Tomcat 的 DB 数据源,因为不想在项目文件中进行 DB 设置。

我目前不考虑在 Spring 项目中使用数据源。

当前设置

Spring 项目的事务管理器使用 Tomcat DBCP 池和 Oracle 数据源(oracle.jdbc.OracleDriver with javax.sql.DataSource)

applicationContext.xml - 数据库设置

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:/comp/env/jdbc/svc"/>
    <property name="resourceRef" value="true"/>
</bean> 

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="mapperLocations" value="classpath*:../sql/**.xml"/>
    <property name="dataSource"><ref bean="dataSource"/></property>
</bean>

<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
    <constructor-arg ref="sqlSessionFactory"/>
</bean>

<bean id="oracleTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource" />
<bean id="transactionManager" class="com.xxx.xxx.api.transaction.TransactionManager">
    <property name="transactionManagers">
        <list>
            <ref bean="oracleTransactionManager"/>
        </list>
    </property>
</bean>

正在尝试...记录数据库池状态

每当调用某个 dao 类中的函数时,我都会尝试使用 Spring Aspect 编写日志。 我要写的日志就像 DB Pool status 之类的

  1. 活动连接数
  2. 空闲连接计数
  3. 最大活动连接设置
  4. 最大空闲连接设置

等等。

问题

是否可以从 spring 项目中访问 Tomcat 的数据库池? 下面会有类似的方法。

  1. getNumIdle()
  2. getWaitCount()
  3. getNumActive()

【问题讨论】:

    标签: java spring oracle tomcat


    【解决方案1】:

    您可以简单地为tomcatJdbcPoolDataSource 创建一个代理并将其用作spring bean。我为 C3P0 池化数据源创建了一个代理。我稍后使用所需的配置创建了我的类的 spring bean 并将其用作数据源。我相信你可以做类似的事情。

    public class C3PODataSourceProxy extends AbstractComboPooledDataSource {
    
        public C3PODataSourceProxy() {
            super();
        }
    
        public C3PODataSourceProxy(boolean autoregister) {
            super(autoregister);
        }
    
        public C3PODataSourceProxy(String configName) {
            super(configName);
        }
    
        @Override
        public Connection getConnection() throws SQLException {
            try {
                Connection connection = super.getConnection();
                //You can call the below methods and log it, send it to some other class etc
                getNumIdleConnections();
                getNumBusyConnections();
                return connection;
            } catch (Exception exception) {
                //log the exception
                throw exception;
            }
        }
    
        public Connection getConnection(String username, String password) throws SQLException {
    
            try {
                Connection connection = super.getConnection(username, password);
                   //You can call the below methods and log it, send it to some other class etc
                getNumIdleConnections(username, password);
                getNumBusyConnections(username, password);
                return connection;
            } catch (Exception exception) {
                //log the exception
                throw exception;
            }
        }
    
    }
    

    【讨论】:

    • 感谢您的回答,我会看看它是否适用于我的项目。
    • 我能够设置 driverspy 并且可以看到计数。也解决了问题。如果使用相同 sid 的任何应用程序多次尝试使用错误密码登录而没有锁定整个 sid 的策略,oracle db 会出现导致内存锁定的错误。查找密码错误的守护进程,并解决了延迟进程。感谢您的提问。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-11
    • 1970-01-01
    • 1970-01-01
    • 2010-12-22
    • 2014-04-01
    • 1970-01-01
    • 2011-07-15
    相关资源
    最近更新 更多