1. 问题背景
微信公众号后台在调试过程中出现调用下发控制指令接口是dump的情况,经过gdb调试及打印信息输出排查后,可能原因是客户端并行发起请求时对数据库的打开和关闭操作冲突导致。考虑加锁或者单例可能会对数据库的操作效率降低,建议使用数据库连接池,通过数据库连接池来同时维护多个数据库实例的连接,这样既解决了并行访问时数据库连接实例的分配问题,也保证了效率。
2. 数据库连接池使用
2.1. 概念
连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。而连接的建立、断开都由连接池自身来管理。同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数以及每个连接的最大使用次数、最大空闲时间等等。也可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。
2.2. 数据库连接池libzdb
目前比较流行的数据库连接池有dbcp、c3p0、proxool等基于java的数据库连接池,另外还有性能更为稳定的商业中间件weblogic、websphere所自带的数据库连接池。以上所列举的数据库连接池主要基于java开发。下面将着重介绍基于c语言开发的,可以在c、c++项目中使用的libzdb数据库连接池。
Libzdb 实现了一个小型、快速和易用的线程安全的连接池数据库API,可连接多种数据库,零配置,通过URL指定连接信息。它具有以下特性:
· 线程安全的数据库连接池
· 连接到多个数据库系统
· 零配置,通过URL指定连接信息
· 支持MySQL, PostgreSQL, SQLite and Oracle 可以不断进行扩展。
· 支持平台及开发语言:支持ios、Linux、FreeBSD、Solaris、OpenBSD和其他 POSIX 系统,支持C、C++、Object C
2.3. 各模块简单分析
Exception
异常模块,主要是为整个系统提供异常处理接口。处理异常包括数据库异常和内存异常等其他非法操作。捕获异常的好处是,不使程序由于异常而非法退出。
System
一些时间处理、内存操作、系统操作等接口。方便其他模块调用。
Net
统一资源定位符(UniformResource Locator,缩写为URL)是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。
整个数据库的初始化和代理对象的初始化,都是通过这个URL来进行处理。
示例:
mysql://localhost:3306/test?user=root&password=swordfish
这个模块式针对这个URL地址进行处理的函数接口。
Util
这个模块主要负责一些工具的封装,封装了字符串的处理函数,还封装了面向对象中的向量(vector)、StringBuffer等工具,方面整个模块的处理。
Db
这个模块主要包括实现连接代理模式、结果集代理模式、SQL语句代理模式和数据库连接池、各类数据库连接的真实实现等。这个模块是整个程序的核心。
2.4. 连接池使用流程
一、根据URL对象创建连接池:
URL对象通过char* 形式的URL生成,url中已经包含数据库类型,数据库名 用户密码等参数。形如:
MYSQL访问:
mysql://localhost:3306/test?user=root&password=swordfish
mysql://root:swordfish@localhost:3306/test
ORACLE访问:
oracle://localhost:1521/test?user=scott&password=tiger
oracle:///servicename?user=scott&password=tiger
二、开启连接池
ConnectionPool_new(URL_T url) 根据URL生成连接池对象ConnectionPool_T,
ConnectionPool_start(ConnectionPool_T t); 开启数据库连接池(默认连接池大小为5),如果想自定义,需在开启前使用ConnectionPool_setInitialConnections函数设置。用法如下:
从数据库池中获取一个连接(此时活动连接+1):Connection_T ConnectionPool_getConnection (T P);
使用完毕后将连接放回连接池(此时活动连接-1):void Connection_close (Connection_T C)
或者voidConnectionPool_returnConnection (T P, Connection_T connection)
三、获取连接之后,执行数据库SQL语句
此处T 代表 Connection_T , Connection_execute 用于执行数据库插入、更新、删除等操作。Connection_executeQuery用于数据库查询,返回结果集。
四、结果及操作函数
游标移动至结果集下一行intResultSet_next (ResultSet_T R), 结果无下一行则返回false ,否则返回true。关于结果集其他操作函数如下
可用的参考例程如下:
3. PRS7000运营管理系统优化方案
当前程序中webservice提供给app调用的接口函数中存在大量查询数据库的操作,通过如下方式进行(以获取充电用户信息为例)
通过打开一个数据库实例连接到数据库,再通过封装的CADORecordset类来执行sql语句,并对返回的结果集进行处理。
对比数据库连接池libzdb的范例可知,libzdb中对于数据库的连接、数据的查询、结果集的返回提供了良好的接口类的封装。所以本次主要工作为结合7000系统的接口业务,对连接池查询返回的结果集进行深层封装,以满足我们自身的业务需求。
数据库连接池的启动则在scadamaster中完成,通过将
4. 参考网址:
官方API参考网址:http://www.tildeslash.com/libzdb/#api
其他参考博客:http://blog.csdn.net/zhu2695/article/details/51571342