0 0

用Spring+Hibernate搭建SOCKET通讯服务,使用C3P0做连接池,发现死锁问题10

Spring+Hibernate搭建SOCKET通讯服务,数据库为oracle,C3P0作为连接池,SOCKET通讯方式为:启动一个线程监听socket连接,然后为每个socket连接创建一个线程,专门负责这个连接的通讯线程,对于传入的数据,通过分析通讯规约调用spring服务进行业务处理,spring服务方法中需要调用数据库操作。现在发现socket客户数量一多起来,就会死锁,执行jstack后结果如下:
"9000-106.39.223.149:4241" prio=6 tid=0x49024c00 nid=0x1a10 in Object.wait() [0x63e4f000..0x63e4fb18]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0x07d2a098> (a com.mchange.v2.resourcepool.BasicResourcePool)
	at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1315)
	at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:557)
	- locked <0x07d2a098> (a com.mchange.v2.resourcepool.BasicResourcePool)
	at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:477)
	at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:525)
	at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128)
	at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:81)
	at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)
	at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)
	at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:160)
	at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:81)
	at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1473)
	at org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:555)
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:335)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:105)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
	at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)
	at com.lily.dap.service.socket.command.LoginCommand$$EnhancerByCGLIB$$1a972c56.execute(<generated>)
	at com.lily.dap.service.socket.task.TaskExecutor.execute(TaskExecutor.java:48)
	at com.lily.dap.service.socket.listen.Handler.run(Handler.java:232)
	at java.lang.Thread.run(Thread.java:619)

   Locked ownable synchronizers:
	- None

"9000-36.59.241.72:35010" prio=6 tid=0x48f2c400 nid=0x188c in Object.wait() [0x63dff000..0x63dffb98]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0x07d2a098> (a com.mchange.v2.resourcepool.BasicResourcePool)
	at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1315)
	at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:557)
	- locked <0x07d2a098> (a com.mchange.v2.resourcepool.BasicResourcePool)
	at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:477)
	at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:525)
	at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128)
	at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:81)
	at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)
	at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)
	at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:160)
	at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:81)
	at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1473)
	at org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:555)
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:335)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:105)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
	at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)
	at com.lily.dap.service.socket.command.LoginCommand$$EnhancerByCGLIB$$1a972c56.execute(<generated>)
	at com.lily.dap.service.socket.task.TaskExecutor.execute(TaskExecutor.java:48)
	at com.lily.dap.service.socket.listen.Handler.run(Handler.java:232)
	at java.lang.Thread.run(Thread.java:619)

   Locked ownable synchronizers:
	- None
...

经过统计,有1116个线程都是这个输出信息。
c3p0配置如下:
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
      <property name="driverClass" value="${hibernate.connection.driver_class}"/>
      <property name="jdbcUrl" value="${hibernate.connection.url}"/>
      <property name="properties">
        <props>
            <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> 
            <prop key="c3p0.minPoolSize">50</prop> 
            <prop key="hc3p0.maxPoolSize">200</prop> 
            <prop key="hc3p0.timeout">100</prop> 
            <prop key="c3p0.max_statement">50</prop> 
            <prop key="c3p0.testConnectionOnCheckout">true</prop> 
            <prop key="hibernate.c3p0.testConnectionOnCheckout">false</prop>
	        <prop key="user">${hibernate.connection.username}</prop>
	        <prop key="password">${hibernate.connection.password}</prop>
        </props>
      </property>
    </bean>

事务配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"
	default-lazy-init="true">
	<description>Spring DAO 配置文件</description>

	<bean id="dao" class="com.lily.dap.dao.hibernate.HibernateDao">
        <property name="sessionFactory" ref="sessionFactory"/>
        <property name="batchSize" value="20"/>
	</bean>

	<!-- Hibernate配置 -->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="namingStrategy">
			<bean class="org.hibernate.cfg.ImprovedNamingStrategy" />
		</property>
        <property name="hibernateProperties">
            <value>
                hibernate.dialect=${hibernate.dialect}
                hibernate.query.substitutions=true 'Y', false 'N'
                hibernate.show_sql=${hibernate.show_sql}
                hibernate.format_sql=true
                hibernate.cache.use_second_level_cache=true
                hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
            </value>
        </property>
		<property name="packagesToScan" value="com.lily.dap.entity" />
	</bean>
	
	<!-- 事务管理器配置,单数据源事务 -->
	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>

	<!-- 使用annotation定义事务 -->
	<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
 </beans>

spring启动代码如下:
public class SocketMain {
	public static void main(String[] args) {
		URL url = SocketMain.class.getResource("/config/log4j.properties");
		PropertyConfigurator.configure(url);
		
//		url = SocketMain.class.getResource("/config/ehcache.xml");
//		CacheManager.create(url);
		
		BeanFactory factory = new ClassPathXmlApplicationContext("classpath:config/applicationContext.xml");  
		
		ServiceSocketManager attachmentServiceSocketManager = (ServiceSocketManager)factory.getBean("attachmentServiceSocketManager");
		attachmentServiceSocketManager.startService();
		
		ServiceSocketManager serviceSocketManager = (ServiceSocketManager)factory.getBean("serviceSocketManager");
		serviceSocketManager.startService();
		
		ServiceSocketManager commandServiceSocketManager = (ServiceSocketManager)factory.getBean("commandServiceSocketManager");
		commandServiceSocketManager.startService();
...

请帮忙解决分析一下是什么原因。

问题补充:现在发现和oracle有关,我减小了连接池数量,c3p0.minPoolSize=10,hc3p0.maxPoolSize=20,连接一个本地局域网内的测试oracle,写了个socket客户端大并发测试,没有堵塞,打印连接池信息,如下:
getNumConnectionsDefaultUser - 9
getNumIdleConnectionsDefaultUser - 6
getNumBusyConnectionsDefaultUser - 3
getNumUnclosedOrphanedConnectionsDefaultUser - 0
getStatementCacheNumStatementsDefaultUser - 0
getStatementCacheNumCheckedOutDefaultUser - 0
getStatementCacheNumConnectionsWithCachedStatementsDefaultUser - 0
getNumThreadsAwaitingCheckoutDefaultUser - 0
连接实际运营的数据库,有堵塞,打印连接池信息,如下:
getNumConnectionsDefaultUser - 15
getNumIdleConnectionsDefaultUser - 0
getNumBusyConnectionsDefaultUser - 15
getNumUnclosedOrphanedConnectionsDefaultUser - 0
getStatementCacheNumStatementsDefaultUser - 0
getStatementCacheNumCheckedOutDefaultUser - 0
getStatementCacheNumConnectionsWithCachedStatementsDefaultUser - 0
getNumThreadsAwaitingCheckoutDefaultUser - 296
客户的oracle现在不好重装,请教客户oracle配置有什么问题吗

问题补充:通过查资料,发现可以通过优化C3P0配置缓解这个问题,优化如下:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
   <property name="driverClass" value="${hibernate.connection.driver_class}" />
   <property name="jdbcUrl" value="${hibernate.connection.url}" />
   <property name="user" value="${hibernate.connection.username}" />
   <property name="password" value="${hibernate.connection.password}" />
  
   <property name="minPoolSize" value="${c3p0.miniPoolSize}" />
   <property name="maxPoolSize" value="${c3p0.maxPoolSize}"/> 
   <property name="initialPoolSize" value="${c3p0.initialPoolSize}"/>
   <property name="maxIdleTime" value="${c3p0.maxIdleTime}"/>
   <property name="acquireIncrement" value="${c3p0.acquireIncrement}"/>
 
   <property name="acquireRetryAttempts" value="${c3p0.acquireRetryAttempts}"/>
   <property name="acquireRetryDelay" value="${c3p0.acquireRetryDelay}"/>
   <property name="testConnectionOnCheckin" value="${c3p0.testConnectionOnCheckin}"/>
   <property name="automaticTestTable" value="${c3p0.automaticTestTable}"/>
   <property name="idleConnectionTestPeriod" value="${c3p0.idleConnectionTestPeriod}"/>
   <property name="checkoutTimeout" value="${c3p0.checkoutTimeout}"/>
</bean>   
对应database.propertites
c3p0.miniPoolSize = 10
c3p0.maxPoolSize = 20
c3p0.initialPoolSize = 10
c3p0.maxIdleTime = 60
c3p0.acquireIncrement = 1

c3p0.acquireRetryAttempts = 30
c3p0.acquireRetryDelay = 100
c3p0.testConnectionOnCheckin = true
c3p0.automaticTestTable = c3p0TestTable
c3p0.idleConnectionTestPeriod = 60
c3p0.checkoutTimeout=3000
这样优化后,有时候也还是会堵塞,但不会一直堵塞
2014年10月28日 09:34

1个答案 按时间排序 按投票排序

0 0

没看出来有什么死锁,所有的线程都在等待可用的数据库连接,可能是你的数据库操作太费时了,导致连接不能及时的释放,你可以打印一下连接池的可用连接数跟踪下

2014年10月28日 11:13

相关推荐

    c3p0连接池

    C3P0连接池,最常用的连接池技术!

    C3P0中文文档说明

    c3p0是现在用的最多连接池之一,这么成功的项目却只是一个人开发的。 当目标很明确(连接池要做什么,目标是非常明确的),使用场景很普通的时候,项目能成功,完全求决于程序的架构. 项目在jmx管理和本身死锁监测,做的...

    操作系统实验六 死锁问题实验

    操作系统实验六:死锁问题实验报告。通过本实验观察死锁产生的现象,考虑解决死锁问题的方法。从而进一步加深对于死锁问题的理解。掌握解决死锁问题的几种算法的编程和调试技术。练习怎样构造管程和条件变量,利用...

    车辆行驶死锁问题

    车辆行驶死锁问题,在Linux下用C语言完成下面模型:设有一个T型路口,其中A,B,C,D各处可容纳一辆车,车型方向如图所示。找出死锁并用有序分配法消除之,要求资源编号合理。

    Mybatis update数据库死锁之获取数据库连接池等待

    主要介绍了Mybatis update数据库死锁之获取数据库连接池等待的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下

    哲学家就餐问题与死锁问题

    操作系统死锁问题 C语言实现 有详细代码 都能实现

    操作系统死锁问题

    进程死锁的检测:资源分配图的化简判断是否有死锁发生

    解决ORACLE死锁问题

    一、数据库死锁的现象 程序在执行的过程中,点击确定或保存按钮,程序没有响应,也没有出现报错。 二、死锁的原理 当对于数据库某个表的某一列做更新或删除等操作,执行完毕后该条语句不提 交,另一条对于这一列...

    p264 - p276 死锁

    p264 - p276 死锁

    哲学家进餐问题死锁的造成.cpp

    死锁的四个条件: (1) 互斥条件:一个资源每次只能被一个进程使用。 (2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。 (3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行...

    数据库死锁-解决死锁问题的三种办法

    解决死锁问题的三种方法:预防死锁,检测死锁及避免死锁。

    Java解决死锁问题eclipse代码版

    Java解决死锁问题eclipse代码版

    操作系统-死锁

    从进程同步的概念可以知道,当并发进程需要竞争使用资源或需要相互协作向前推进时,如果不采取同步措施,或同步措施不恰当,则很容易导致并发进程不能向前推进而陷入僵局,即死锁现象。死锁是发生在一组相互竞争或...

    关于Oracle数据库死锁问题的研究与讨论

    关于Oracle数据库死锁问题的研究与讨论

    用银行家算法预防解答死锁问题

    用银行家算法预防死锁 #include using namespace std; #define MAXPROCESS 50 /*最大进程数*/ #define MAXRESOURCE 100 /*最大资源数*/ int AVAILABLE[MAXRESOURCE]; /*可用资源数组*/ int MAX[MAXPROCESS]...

    mysql死锁分析

    mysql死锁分析

    db2死锁问题.doc

    db2死锁问题.doc db2死锁问题.docdb2死锁问题.docdb2死锁问题.docdb2死锁问题.docdb2死锁问题.docdb2死锁问题.docdb2死锁问题.docdb2死锁问题.docdb2死锁问题.docdb2死锁问题.doc

    银行家问题--避免死锁

    对系统资源的申请和分配,主要是为了避免死锁问题。

    山东大学操作系统实验6死锁问题

    山东大学 操作系统实验6 死锁问题实验的程序

    操作系统中的死锁问题

    有关死锁的介绍。包括死锁的定义,如何处理死锁,死锁如何预防,如何避免等

Global site tag (gtag.js) - Google Analytics