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
这样优化后,有时候也还是会堵塞,但不会一直堵塞
相关推荐
C3P0连接池,最常用的连接池技术!
c3p0是现在用的最多连接池之一,这么成功的项目却只是一个人开发的。 当目标很明确(连接池要做什么,目标是非常明确的),使用场景很普通的时候,项目能成功,完全求决于程序的架构. 项目在jmx管理和本身死锁监测,做的...
操作系统实验六:死锁问题实验报告。通过本实验观察死锁产生的现象,考虑解决死锁问题的方法。从而进一步加深对于死锁问题的理解。掌握解决死锁问题的几种算法的编程和调试技术。练习怎样构造管程和条件变量,利用...
车辆行驶死锁问题,在Linux下用C语言完成下面模型:设有一个T型路口,其中A,B,C,D各处可容纳一辆车,车型方向如图所示。找出死锁并用有序分配法消除之,要求资源编号合理。
主要介绍了Mybatis update数据库死锁之获取数据库连接池等待的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
操作系统死锁问题 C语言实现 有详细代码 都能实现
进程死锁的检测:资源分配图的化简判断是否有死锁发生
一、数据库死锁的现象 程序在执行的过程中,点击确定或保存按钮,程序没有响应,也没有出现报错。 二、死锁的原理 当对于数据库某个表的某一列做更新或删除等操作,执行完毕后该条语句不提 交,另一条对于这一列...
p264 - p276 死锁
死锁的四个条件: (1) 互斥条件:一个资源每次只能被一个进程使用。 (2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。 (3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行...
解决死锁问题的三种方法:预防死锁,检测死锁及避免死锁。
Java解决死锁问题eclipse代码版
从进程同步的概念可以知道,当并发进程需要竞争使用资源或需要相互协作向前推进时,如果不采取同步措施,或同步措施不恰当,则很容易导致并发进程不能向前推进而陷入僵局,即死锁现象。死锁是发生在一组相互竞争或...
关于Oracle数据库死锁问题的研究与讨论
用银行家算法预防死锁 #include using namespace std; #define MAXPROCESS 50 /*最大进程数*/ #define MAXRESOURCE 100 /*最大资源数*/ int AVAILABLE[MAXRESOURCE]; /*可用资源数组*/ int MAX[MAXPROCESS]...
mysql死锁分析
db2死锁问题.doc db2死锁问题.docdb2死锁问题.docdb2死锁问题.docdb2死锁问题.docdb2死锁问题.docdb2死锁问题.docdb2死锁问题.docdb2死锁问题.docdb2死锁问题.docdb2死锁问题.doc
对系统资源的申请和分配,主要是为了避免死锁问题。
山东大学 操作系统实验6 死锁问题实验的程序
有关死锁的介绍。包括死锁的定义,如何处理死锁,死锁如何预防,如何避免等