使用boost::circular_buffer_space_optimized实现OTL数据库连接池
来源:互联网 发布:淘宝上的吉他店 编辑:程序博客网 时间:2024/06/07 04:59
引言
数据库连接是一种关键的有限的昂贵的资源,因此对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标。数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而再不是重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。
数据库连接池的关键因素
1.容器
数据库连接池是数据库连接的集合,必须要有容器来存储这些连接,许多方法都是用stl的list、queue、vector常用的容器来实现的,但今天我选择了circular_buffer_space_optimized来实现,具体介绍可到www.boost.org上查看。
2.最小连接数
数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数来设定的。无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量。
3.最大连接数
连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。
4.连接的使用
最先的连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接。不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,它将被放到连接池中等待重复使用或是空闲超时后被释放。获得连接的请求使用完之后,要把连接放回容器当中,以便之后的请求重复使用,达到重复利用的目的。
实现代码
当然,我也不完全按照上面的主要因素来实现的,可根据circular_buffer_space_optimized和OTL的特性实现了一个简单的数据库连接池。
//数据库连接池虚类db_conn_pool.h
- #pragma once
- #include <iostream>
- #include <boost/circular_buffer.hpp>
- #include <boost/shared_ptr.hpp>
- #include <boost/thread/mutex.hpp>
- template <class conn>
- class db_conn_pool
- {
- public:
- typedef conn connection;
- typedef boost::shared_ptr<conn> connection_ptr;
- virtual connection_ptr getConnection() = 0;
- virtual void initConnection() = 0;
- int size(){return m_conn_container.size();}
- protected:
- std::string m_conn_str;
- unsigned short m_max_size;
- boost::circular_buffer_space_optimized<connection_ptr> m_conn_container;
- boost::mutex m_mutex;
- db_conn_pool(){}
- db_conn_pool(const std::string& conn_str, unsigned short max_size)
- :m_conn_str(conn_str), m_max_size(max_size)
- {
- }
- virtual connection_ptr createConnection() = 0;
- };
- template<class conn_pool, class conn>
- class connection_wrap{
- public:
- connection_wrap(conn_pool& pool, boost::shared_ptr<conn> ptrConn)
- :m_pool(pool), m_ptrConn(ptrConn)
- {
- }
- ~connection_wrap()
- {
- m_pool.releaseConnection(m_ptrConn);
- }
- private:
- boost::shared_ptr<conn> m_ptrConn;
- conn_pool& m_pool;
- };
//mysql数据库连接池my_conn_pool.h
- #pragma once
- #include <iostream>
- #define OTL_ODBC // CompileOTL 4.0/ODBC
- // Thefollowing #define is required with MyODBC 5.1 and higher
- #define OTL_ODBC_SELECT_STM_EXECUTE_BEFORE_DESCRIBE
- #define OTL_STL
- #include "otlv4.h"
- #include "db_conn_pool.h"
- #include <boost/format.hpp>
- #include <firebird/log/logger_log4.hpp>
- //FUNC DEFINE
- #define OTL_STREAM _otl_stream
- #define OTL_EOF _otl_stream.eof()
- #define OTL_SUCCEED 0
- #define OTL_FAILED -1
- #define OTL_NO_DATA_FOUND 1403
- #define OTL_BEGIN(conn, sql) \
- try { \
- LOG4CXX_DEBUG(console_log, KDS_CODE_INFO << sql); \
- otl_stream _otl_stream(100, sql, *conn);
- #define OTL_END(conn, _count) \
- _otl_stream.flush(); \
- _count = _otl_stream.get_rpc(); \
- } catch (otl_exception& otl_exp) { \
- print_exception(otl_exp); \
- if(otl_exp.code == 2006) \
- { \
- conn->logoff(); \
- } \
- throw business_error(otl_exp.code, (char*)(otl_exp.msg)); \
- }
- #define OTL_COMMIT(conn) conn->commit();
- #define OTL_ROLLBACK(conn) conn->rollback();
- static void print_exception(otl_exception& otl_exp)
- {
- boost::format fmt("otl with exception:[%1%][%2%][%3%]");
- std::string str = boost::str(fmt
- % otl_exp.code
- % otl_exp.msg
- % otl_exp.stm_text);
- LOG4CXX_ERROR(console_log, KDS_CODE_INFO << str);
- }
- class mysql_conn_pool : public db_conn_pool<otl_connect>
- {
- public:
- ~mysql_conn_pool();
- static mysql_conn_pool& getInstance();
- void setParam(const std::string& conn_str, unsigned short max_size);
- connection_ptr getConnection();
- void releaseConnection(connection_ptr ptrConn);
- void initConnection();
- protected:
- typedef db_conn_pool<otl_connect> super;
- mysql_conn_pool();
- private:
- connection_ptr createConnection();
- };
//my_conn_pool.cpp
- #include "mysql_conn_pool.h"
- #include <boost/typeof/typeof.hpp>
- mysql_conn_pool::mysql_conn_pool()
- {
- }
- mysql_conn_pool::~mysql_conn_pool()
- {
- }
- mysql_conn_pool& mysql_conn_pool::getInstance()
- {
- static mysql_conn_pool pool;
- return pool;
- }
- void mysql_conn_pool::setParam(const std::string& conn_str, unsigned short max_size)
- {
- m_conn_str = conn_str;
- m_max_size = max_size;
- }
- void mysql_conn_pool::initConnection()
- {
- m_conn_container.resize(m_max_size);
- otl_connect::otl_initialize(1); // initialize the database API environment
- for (int i = 0; i < m_max_size; ++i)
- {
- createConnection();
- }
- }
- mysql_conn_pool::connection_ptr mysql_conn_pool::getConnection()
- {
- connection_ptr ptrConn;
- std::time_t begin;
- std::time(&begin);
- while(1)
- {
- boost::mutex::scoped_lock lock(m_mutex);
- if (m_conn_container.size() == 0)
- {
- std::time_t now;
- std::time(&now);
- if (now - begin > 10)
- {
- /*
- *若超过10秒还没取得连接对象,则认为连接池里的连接都失效用完,
- *应重新创建
- */
- createConnection();
- begin = now;
- }
- continue;
- }
- ptrConn = m_conn_container.front();
- m_conn_container.pop_front();
- if (ptrConn != NULL && ptrConn->connected)
- {
- /*BOOST_AUTO(pos, m_conn_container.begin());
- m_conn_container.rotate(++pos);*/
- break;
- }
- else
- {
- //m_conn_container.pop_front();
- createConnection();
- continue;;
- }
- }
- return ptrConn;
- }
- mysql_conn_pool::connection_ptr mysql_conn_pool::createConnection()
- {
- connection_ptr ptrConn(new otl_connect());
- ptrConn->rlogon(m_conn_str.c_str());
- if (ptrConn != NULL && ptrConn->connected)
- {
- ptrConn->auto_commit_on();
- ptrConn->set_timeout(60);
- m_conn_container.push_back(ptrConn);
- }
- return ptrConn;
- }
- void mysql_conn_pool::releaseConnection(connection_ptr ptrConn)
- {
- boost::mutex::scoped_lock lock(m_mutex);
- if (ptrConn != NULL && ptrConn->connected)
- {
- m_conn_container.push_back(ptrConn);
- }
- }
//测试test.cpp
- #include <iostream>
- #include "my_conn_pool.h"
- int main()
- {
- mysql_conn_pool& m_mysql_pool = mysql_conn_pool::getInstance();
- m_mysql_pool.setParam("Driver={MySQL ODBC 5.2w Driver};Server=127.0.0.1;Port=3306;Database=opensips;Uid=root;Pwd=123321", 10);
- m_mysql_pool.initConnection();
- mysql_conn_pool::connection_ptr pConn = m_mysql_pool.getConnection();
- connection_wrap<mysql_conn_pool, mysql_conn_pool::connection> wrap(m_mysql_pool, pConn);
- std::string sql;
- sql = "delete from account_bind where ext_acct = :f1<char[50]>";
- int count = 0;
- OTL_BEGIN(pConn, sql.c_str());
- OTL_STREAM << req.sExtAcct;
- OTL_END(pConn, count);
- return 0;
- }
- 使用boost::circular_buffer_space_optimized实现OTL数据库连接池
- 使用boost::circular_buffer_space_optimized实现OTL数据库连接池
- 使用boost::circular_buffer_space_optimized实现OTL数据库连接池
- otl 数据库连接
- 使用boost的any和otl库来实现通用的数据库操作
- otl 使用
- OTL 4.0, OTL缓冲池
- mysql数据库连接池使用(二)实现自己的数据库连接池
- 使用c3p0-0.9.2实现数据库连接池
- 使用OTL连接Oracle
- Otl使用初步
- OTL使用总结
- OTL的使用
- OTL使用问题汇总
- 使用数据库连接池建立数据库连接
- OTL
- 使用OTL来访问数据库
- 使用OTL进行数据库编程
- DRIVER_ATTR and DEVICE_ATTR
- Linux下的多进程编程
- vs2010 js/css 代码折叠
- twitter storm安装和storm-start的本地运行
- 字段摘要是干什么的?
- 使用boost::circular_buffer_space_optimized实现OTL数据库连接池
- H.264 Profile、Level、Encoder三张简图
- HTML服务器推送技术简介
- Java中的Class类又是什么?
- daemon守护进程
- [ios开发]利用有道翻译API实现简单的翻译功能
- getDeclaredMethod方法和getMethod方法区别?
- MySql实现远程连接
- spring 整合 axis 实现webservice