• 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;
    %s.
    ", __FILE__, __LINE__,
                    "SyncExecSQL(FUNCCALL fun)");
                return bResult;
            }
            try
            {
                fun(pWrapper);
                bResult = true;
            }
            catch (const string& e)
            {
                gLog.LogText(LOG_ERROR,
                    "%s:%d;
    %s.
    ", __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] = { '' };
                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());
    }
  • 相关阅读:
    如何在服务器上添加本地驱动器
    JQ查找到带有某个字符,并起类名,然后替换这个某个字符
    使用IWMS的网站打开显示“未能加载文件或程序集”,解决方案
    表头固顶结构
    在页面中有overflow-y:auto属性的div,当出现滚动条,点击返回顶部按钮,内容回这个div最顶部
    在文档页面整个区域出现导航随内容滚动高亮显示效果
    在文档页面局部出现导航随内容滚动高亮显示效果
    在Hmtl页面中只让其中单独的一个div隐藏滚动条但是仍可滚动浏览下边的内容
    GC参考手册 —— GC 调优(工具篇)
    GC参考手册 —— GC 算法(实现篇)
  • 原文地址:https://www.cnblogs.com/osbreak/p/9979448.html
Copyright © 2020-2023  润新知