前几天开发一个多线程执行的任务,在多线程执行的时候,一直在报错,如下:
An attempt by a client to checkout a Connection has timed out.
com.mchange.v2.resourcepool.TimeoutException: A client timed out while waiting to acquire a resource from com.mchange.v2.resourcepool.BasicResourcePool@29426a4 -- timeout at awaitAvailable()
从异常信息能够看出,是数据库的连接池满了,然而还有新的线程去获取连接池,在获取新连接超过一定时间(用checkoutTimeout配置)后,就会报以上的错误。
从网上查到一些遇到相同问题的情况,但是都没真正解决我的问题。
有人说是c3p0在连接使用完毕之后,statement有可能会被缓存,从而导致connection没有真正的关闭掉,当有其他线程获取连接的时候,就获取不到了。但c3p0是默认关闭缓存的,从以下代码可以看出,必须配置maxStatements或maxStatementsPerConnection,若是不配置,它们的默认值都为0,也即不使用用缓存。
if (maxStatements > 0 && maxStatementsPerConnection > 0) this.scache = new DoubleMaxStatementCache( taskRunner, deferredStatementDestroyer, maxStatements, maxStatementsPerConnection ); else if (maxStatementsPerConnection > 0) this.scache = new PerConnectionMaxOnlyStatementCache( taskRunner, deferredStatementDestroyer, maxStatementsPerConnection ); else if (maxStatements > 0) this.scache = new GlobalMaxOnlyStatementCache( taskRunner, deferredStatementDestroyer, maxStatements ); else this.scache = null;
既然是获取新连接超时,那就说明一下几点:
1、连接未正常关闭
2、连接池已经满了
3、线程数比连接数多
4、sql执行慢,占用连接时间长
从这几点中,可以分别调整
1、检查程序,是否连接未执行关闭操作
2、调整数据库连接数,但不是连接数越多越好,还得考虑线程数量
3、增加线程休眠时间,或减少线程数,但要保证业务的准确性,线程数可比数据库连接数多,可以综合数据库连接数、获取新连接超时时间(checkoutTimeout)、sql执行时间以及线程休眠时间来大致算出线程数的合适值
4、优化sql,尽量减少sql的执行时间,不要使用大sql,拆分sql执行
5、在获取失败之后,要有重试机制,保证业务正常执行
6、优化程序和数据库之间的网络
7、适当增加acquireIncrement的值,默认为3
最后举个例子
checkoutTimeout配置为3000,也就是超时时间为3000毫秒
maxPoolSize为15,默认值就是15
每个线程执行sql的时间都是10ms,那么同时执行的线程数最好低于4500个=(checkoutTimeout / 10ms) * maxPoolSize
相关推荐
这通常是由于每个线程创建一个独立的数据库连接导致的,当并发线程数量增加时,连接池中的连接数量也随之增加,如果超过服务器允许的最大连接数,就可能导致应用程序无法正常工作,甚至引发“Too many connections”...
- **最小/最大连接数**:设置合适的最小和最大连接数,平衡资源使用和性能需求。 - **连接检测**:定期检查连接有效性,防止因网络或其他问题导致的死连接。 - **连接重用策略**:根据连接的使用频率和状态决定...
- **性能监控**:使用JProfiler、VisualVM等工具监控线程和内存使用情况,找出性能瓶颈。 通过以上知识的学习和实践,开发者可以熟练地在Java环境中实现多线程数据互导,高效使用数据库连接池,以及进行多表插入...
线程会保持对数据库连接的占用,但不会释放,最终导致连接数不断增加,直至耗尽数据库服务器的连接池。耗尽连接后,PostgreSQL数据库会返回错误信息,如"FATAL: remaining connection slots are reserved for non-...
Java JDBC 数据库连接池...Java JDBC 数据库连接池技术可以解决频繁的数据库连接操作对系统资源的占用,提高系统的性能和可靠性。同时,连接池技术也可以和其它技术结合使用,例如 EJB 技术,实现高效的数据库访问。
Java数据库连接池是Java开发中一个非常重要的技术,它主要用于管理数据库连接,提高数据库操作的效率和性能。在Java应用程序中,频繁地创建和关闭数据库连接会导致大量的系统资源浪费,而连接池则可以复用已建立的...
最大连接数限制了同时打开的数据库连接数,防止资源耗尽。 2. **连接检查与回收**:连接池会定期检查池中的连接是否有效,如若发现超时或异常的连接,会将其从池中移除。同时,当连接归还到池时,也会进行检查,...
数据库连接池是数据库管理中的重要概念,它在Java Web应用中尤其常见,主要用于优化数据库的连接管理和资源利用。自定义数据库连接池是为了更好地适应特定应用的需求,提高数据存取的效率,减少系统开销,避免频繁...
实现数据库连接池时,通常会采用线程安全的设计,因为多个并发的线程可能会同时请求和释放连接。这可能需要使用互斥锁(mutex)、条件变量(condition variable)等同步原语来确保数据一致性。 在给定的压缩包文件...
4. **连接数量的控制**:连接池通常会限制最大连接数,以防止过多的数据库连接导致数据库服务器资源耗尽。 5. **连接超时处理**:如果某个线程长时间未归还连接,连接池可以配置为自动断开该连接,以释放资源供其他...
使用DBCP数据库连接池不仅可以减少频繁创建和销毁数据库连接所带来的开销,还可以更灵活地根据应用程序的需求动态调整连接池的大小,从而提高系统整体性能。此外,通过配置文件来管理数据库连接参数也使得维护更加...
数据库连接池是应用程序管理数据库连接的一种机制,它提高了数据库访问的效率和资源利用率。通过复用已建立的数据库连接,避免了频繁创建和关闭连接所消耗的时间和系统资源。连接池的基本思想是预先创建一定数量的...
数据库连接池是Java开发中非常重要的一个组件,它在处理多线程环境下对数据库资源的高效利用和管理中起着关键作用。C3P0是一个开源的Java连接池实现,它提供了一种灵活且功能强大的数据库连接管理方式。在本文中,...
数据库连接池是现代应用程序开发中的重要组成部分,尤其是在处理大量数据交互的应用中,它极大地提高了数据库操作的效率和系统的稳定性。数据库连接池的概念是预先创建并维护一定数量的数据库连接,这些连接可以被多...
在本文中,我们将讨论针对 WAS 6.1 的性能调优策略,涉及到线程数、JVM、日志和数据库连接等方面的优化。 一、线程数优化 在 WAS 6.1 中,线程数的设置对性能的影响非常大。我们可以通过设置 Web Container 的最大...
在SQL Server 2008中,设置最大连接数是一项重要的系统配置,它关乎到数据库服务器的性能和稳定性。此设置决定了同一时间可以有多少个客户端连接到SQL Server实例。了解并正确配置这个参数对于数据库管理员来说至关...
2. **参数设置文件**:这可能是配置文件,用于设定数据库连接池的相关参数,如最大连接数、最小连接数、超时时间、数据源类型等。这些参数对连接池的性能有直接影响,需要根据应用的实际需求进行调整。 3. **连接池...
总的来说,理解并实现一个简单的数据库连接池可以帮助我们更好地理解和利用这一技术,同时也能锻炼我们的多线程编程和设计能力。在实际项目中,结合maven和其他开源库,我们可以构建出高效、可靠的数据库连接管理...