1. 程式人生 > >Mysql-連線池

Mysql-連線池

#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());
}