第二個工具類:DBService
用于MySQL數據庫服務類的基類。主要處理數據庫連接的建立(Start),斷開(Stop),維持心跳(Ping)。
基于之前的DBOperator實現。
該基類提供兩個虛接口,PRocessStart,ProcessStop,交由子類去實現子類自己的初始化工作,和釋放工作。
建立連接(Start)時,會斷開現有連接(如果有的話,會先調用ProcessStop做清理工作),然后建立新連接,連接建立好之后調用ProcessStart。
斷開連接(Stop)時,調用ProcessStop做清理工作,然后斷開現有連接。
維持心跳(Ping)時,如果發現連接斷開,則重新連接。如果連不上則放棄,等待下一次Ping,或邏輯主動調用Start重新建立連接。
DBService中保存一個建立好的數據庫連接,并加鎖,保證多線程同時訪問DBService時線程安全。
具體會在這個連接上,做哪些數據庫操作,由子類實現。
DBService.h
#ifndef __DBService_H__#define __DBService_H__#include <boost/thread.hpp>struct st_mysql;typedef struct st_mysql MYSQL;namespace common{ namespace db{ class DBService { public: DBService(); virtual ~DBService(); public: // 建立數據庫連接 bool Start(const std::string& hostname, unsigned int port, const std::string& username, const std::string& userkey, const std::string& dbname); virtual bool ProcessStart(); // 維持數據庫連接心跳,校驗鏈接是否斷開,斷開則重連 void Ping(); // 斷開數據庫連接 void Stop(); virtual void ProcessStop(); protected: // 數據庫連接 boost::mutex m_Lock; MYSQL *m_Connect; private: // 建立新鏈接 bool Connect(); // 終止鏈接 void DisConnect(); // 數據庫連接參數 std::string m_HostName; unsigned int m_Port; std::string m_UserName; std::string m_UserKey; std::string m_DBName; }; }}#endifDBService.cpp
#include "DBService.h"#include "Logger.h"using namespace common::tool;#include "DBDefine.h"#include "DBOperator.h"namespace common{ namespace db{ DBService::DBService() { m_Connect = NULL; } DBService::~DBService() { DisConnect(); } bool DBService::Start(const std::string& hostname, unsigned int port, const std::string& username, const std::string& userkey, const std::string& dbname) { boost::mutex::scoped_lock lock(m_Lock); DisConnect(); m_HostName = hostname; m_Port = port; m_UserName = username; m_UserKey = userkey; m_DBName = dbname; return Connect(); } bool DBService::ProcessStart() { return false; } void DBService::Ping() { boost::mutex::scoped_try_lock lock(m_Lock); if (lock.owns_lock()) { if (!DBOperator::Ping(m_Connect)) { DisConnect(); Connect(); } } } void DBService::Stop() { boost::mutex::scoped_lock lock(m_Lock); DisConnect(); } void DBService::ProcessStop() { } bool DBService::Connect() { m_Connect = DBOperator::Connect(m_HostName.c_str(), m_Port, m_UserName.c_str(), m_UserKey.c_str(), m_DBName.c_str()); if (NULL != m_Connect) { if (ProcessStart()) { LOG_INFO(g_LibDBLog) << "connect " << m_HostName << ":" << m_DBName << "@" << m_UserName << " success"; return true; } else { LOG_INFO(g_LibDBLog) << "connect " << m_HostName << ":" << m_DBName << "@" << m_UserName << " error"; DisConnect(); return false; } } else { LOG_INFO(g_LibDBLog) << "connect " << m_HostName << ":" << m_DBName << "@" << m_UserName << " error"; return false; } } void DBService::DisConnect() { if (NULL != m_Connect) { LOG_INFO(g_LibDBLog) << "close " << m_HostName << ":" << m_DBName << "@" << m_UserName; ProcessStop(); DBOperator::DisConnect(m_Connect); m_Connect = NULL; } } }}
新聞熱點
疑難解答