连接池可靠性设计和使用十大场景
数据库连接池是程序中一项宝贵的资源,加之使用频繁,设计与使用稍有考虑不周都可能会影响效率和可靠性。
本文总结了数据库连接池相关的常见可靠性设计,其它类似的资源池也可借鉴。
1. 最小连接数和最大连接数可配置。
有助于在程序运行中根据繁忙程度动态调整, 提高资源利用率;
建议配置最大连接数至少为2,可部分规避同一个线程同时使用2个连接导致的自锁死;
2. 连接池分组:根据具体场景选择”进程”还是”DBName”为单位。
3. 连接池申请要有超时机制,避免程序永久挂死。
可解决由于连接使用不当导致自锁死,超时后程序能自动解开。
4. 通过连接池配置数据库自身的超时机制。
针对网络异常,大事务等异常场景,超时后数据库自动取消该操作,避免程序死等;
该配置值一般要大于业务执行最耗时Sql语句的时间;
网上曾出现过Sybase的API底层ct_cancel函数挂死,Sybase技术支持也建议使用超时来规避。SQLAPI连接池支持在Sybase可配置,一般配置10分钟;
5. 连接池长期不使用时定时释放。
由于数据库支持的总连接数是有限的,长期不使用连接池释放后便于其它有需要的进程使用。
6. 连接池有效性检测,具备数据库异常重启后自恢复,不需要重启进程。
实时检测:连接池释放时,达到老化时间检测一次有效性,以便连接无效时能及时修复;
定时检测:如果发现连接不可用时重建好,新来的连接请求甚至感知不到异常,减少了一次数据库操作失败;
7. 设计连接使用时一般采用Guard模式,及时释放资源。
连接的申请和释放:进入异常分支也能让连接自动释放,避免连接泄露;
事务的启动和回滚:进入异常分支也能让事务自动回滚, 如果事务不提交会严重影响后续数据库操作;
8. 连接池是一把无形的”锁”。
要保证普通锁和连接池申请的顺序,否则可能导致死锁;
9. 连接池是一把”非递归锁”。
连接池是不应重入的,同一个线程最好只使用一个连接,否则以下两种情况会导致挂死。
当连接池只有一个连接,会导致自锁死;
多个线程同时调用该函数,真实案例:连接池有10个连接,10个线程同时调用该函数申请到1个连接,各个现场紧接着再申请下一个连接就会挂死;
轻量级自检测设计方案:在连接池申请和释放的时候动态检测,可集成到连接池中。
10. 快速检测连接有效性
连接池经常用到连接检测,不要指定表名,通常的做法只需简单的Sql语句
select 1
Oracle对应
select 1 from dual
链接池的具体业务流程图如下:
文章如有不妥之处,欢迎指正!谢谢!