Mysql-連線池
阿新 • • 發佈:2018-11-19
#pragma once #include <deque> #include <mutex> #include <boost/thread/thread.hpp> #include <boost/thread/tss.hpp> #include <boost/serialization/singleton.hpp> #include <boost/shared_array.hpp> #include <boost/asio.hpp> #include <thread> #include <queue> #include<atomic> #include <cppconn/driver.h> #include <cppconn/prepared_statement.h> #define DB_CONN_COUNT 4 using namespace std; typedef std::shared_ptr<sql::Connection> CMysqlConnectPtr; #define mysqlMgr MysqlContrlMgr::get_mutable_instance() class MysqlContrlMgr : public boost::serialization::singleton<MysqlContrlMgr> {public: MysqlContrlMgr(); ~MysqlContrlMgr(); void Init(const char* chIp, const char* chUser, const char* chDBName, const char* chPwd, unsigned short uPort = 3306); public: CMysqlConnectPtr GetActiveConnPtr(); void RecodeConnect(CMysqlConnectPtr); protected: STSqlConnParam m_sqlParam;// 資料庫連線資訊結構 CMyMutex m_cs; // 鎖 std::queue<CMysqlConnectPtr> conQueue; // 連線佇列 public: //************************************************************************* // 函式名稱: SyncExecSQL // 返 回 值: bool --執行成功返回true, 否則返回false // 參 數: FUNCCALL fun --可以是回撥函式,仿函式,lambda表示式 // 函式說明: 同步執行一個數據庫操作, //************************************************************************* template<class FUNCCALL> bool SyncExecSQL(FUNCCALL fun) { bool bResult = false; CMysqlConnectPtr pWrapper = GetActiveConnPtr(); if (!pWrapper) { gLog.LogText(LOG_ERROR, "%s:%d;\r\n%s.\r\n", __FILE__, __LINE__, "SyncExecSQL(FUNCCALL fun)"); return bResult; } try { fun(pWrapper); bResult = true; } catch (const string& e) { gLog.LogText(LOG_ERROR, "%s:%d;\r\n%s.\r\n", __FILE__, __LINE__, "SyncExecSQL(FUNCCALL fun)"); } catch (...) { } RecodeConnect(pWrapper); return true; } };
#include "CMysqlMgr.h" static sql::Driver *driver = get_driver_instance(); MysqlContrlMgr::MysqlContrlMgr() { } MysqlContrlMgr::~MysqlContrlMgr() { while (conQueue.size() != 0) { CMysqlConnectPtr con = std::move(conQueue.front()); con->close(); } } //------------------------------------------------------------------------ // 函式名稱: Init // 返 回 值: void // 參 數: //const char* chIp, -- IP //const char* chUser, -- 使用者名稱 //const char* chDBName, -- 資料庫名 //const char* chPwd, -- 密碼 //unsigned short uPort -- 埠 // 說 明: 資料庫連線 初始化 //------------------------------------------------------------------------ void MysqlContrlMgr::Init(const char* chIp, const char* chUser, const char* chDBName, const char* chPwd, unsigned short uPort) { m_sqlParam.m_strIp = chIp; m_sqlParam.m_strUser = chUser; m_sqlParam.m_strDBName = chDBName; m_sqlParam.m_strPwd = chPwd; m_sqlParam.m_uPort = uPort; try { for (int i = 0; i < DB_CONN_COUNT * 10; ++i) { bool b_true = true; char strHonst[100] = { '\0' }; snprintf(strHonst, sizeof(strHonst), "tcp://%s:%d", m_sqlParam.m_strIp.c_str(), m_sqlParam.m_uPort); sql::Connection *conn = driver->connect(strHonst, m_sqlParam.m_strUser.c_str(), m_sqlParam.m_strPwd.c_str()); conn->setClientOption("OPT_CONNECT_TIMEOUT", &m_sqlParam.time_out); conn->setClientOption("OPT_RECONNECT", &b_true); conn->setClientOption("CLIENT_MULTI_RESULTS", &b_true); conn->setClientOption("OPT_CHARSET_NAME", "utf8"); conn->setSchema(m_sqlParam.m_strDBName.c_str()); std::shared_ptr<sql::Connection> sp(conn, [](sql::Connection *conn) { delete conn; }); conQueue.push(std::move(sp)); } } catch (sql::SQLException &e) { gLog.LogText(LOG_ERROR, "%s:%d", __FUNCTION__, e.getErrorCode()); throw "e.getErrorCode"; } cout << "init Mysql Connect Pool success !" << endl; } //------------------------------------------------------------------------ // 函式名稱: GetActiveConnPtr // 返 回 值: void // 參 數: // 說 明: 獲取一個活動的資料庫連線 //------------------------------------------------------------------------ CMysqlConnectPtr MysqlContrlMgr::GetActiveConnPtr() { MyLock(m_cs, CLockableObject::EXCLUSIVE_TYPE); if (conQueue.size() > 0) { CMysqlConnectPtr con = conQueue.front(); conQueue.pop(); return con; } return nullptr; } //------------------------------------------------------------------------ // 函式名稱: RecodeConnect // 返 回 值: void // 參 數: // 說 明: 回收一個數據庫連線 //------------------------------------------------------------------------ void MysqlContrlMgr::RecodeConnect(CMysqlConnectPtr Ptr) { MyLock(m_cs, CLockableObject::EXCLUSIVE_TYPE);; conQueue.push(std::move(Ptr)); cout << "conQueue Size = " << conQueue.size() <<endl; gLog.LogText(LOG_ERROR, "conQueue Size = %d", conQueue.size()); }