Libpqxx connection pool

Libpqxx connection pool

本文关键字:pool connection Libpqxx      更新时间:2023-10-16

我正在尝试使用libpqxx库开发一个非常简单明了的连接池。我对c++还很陌生,对指针和引用仍然很困惑。类的行为非常简单:有一个带有初始化连接的向量,并在需要时将连接弹出和推送到向量上。由于指针和引用的实现不正确,代码中有许多错误。你能给我一些提示吗?

编辑:我设法修复了所有的编译错误。当我运行主函数时,它会给我一个分段错误。

class DbPool {

公用:

pqxx::result runQuery(const string& query) {
connection *conn = getCon();
work trans(*conn);
result res = trans.exec(query);
trans.commit();
releaseCon(conn);
return res;
}
DbPool(uint32_t max_cons) {
for (uint32_t i = 0; i < max_cons; i++) {
connection* con = createCon();
m_freeCons.push_back(shared_ptr < connection > (con));
}
}

私有:

connection * createCon() {
connection * conn =
new connection(
"user='ak' password='rootpassword' dbname='bips_office' hostaddr='127.0.0.1' port='5432'");
return conn;
}
void releaseCon(connection *con) {
m_freeCons.push_back(shared_ptr < connection > (con));
}
connection* getCon() {
shared_ptr < connection > conn = *(m_freeCons.end() - 1);
m_freeCons.pop_back();
return conn.get();
}
vector<shared_ptr<connection> > m_freeCons;

};

int main(int argc, char *argv[]) {
DbPool *pool = new DbPool(5);
result res = pool->runQuery("SELECT COUNT (*) from captures");
return 0;
}

如果你担心设计问题,这里是我的五美分:

  • 您的代码真的编译了吗?我认为不是,因为你有一个指向连接的指针向量,但你正在推回连接指针)
  • 向成员提供可修改的句柄通常是个坏主意(就像您在getCon方法中所做的那样——如果可能的话,至少返回一个connection const *
  • 如果必须使用指针集合,可以考虑使用shared_ptr而不是原始指针,这样就不必担心释放内存;或者使用Boost。PointerContainer;另请参见此处
  • 只是一个奇怪的风格问题:你为什么使用return &(*conn)?这将取消引用指针conn,然后再次获取其地址。相反,您可以简单地编写return conn

在回答您用shared_ptr重新编写的问题时:您仍然需要使用new创建连接,并在其周围封装一个shared_ptr;例如,对于createCon:

connection * createCon(){
connection * conn = new connection("user='ak' password='rootpassword' dbname='bips_office' hostaddr='127.0.0.1' port='5432'");
return conn;
}

connection* con = createCon();
m_freeCons.push_back(shared_ptr<connection>(con));

以及类似地在其它地方。

受您文章的启发,我在自己的项目中使用了这个简单的连接池。我使用了std::stack。推动和弹出。除了添加连接时的try-catch外,没有错误检查。对于postgresql数据库。

数据库.hpp:

#include <stack>
#include <pqxx/pqxx>
class Database {
private:
const std::string connectionString = "dbname=db user=usr hostaddr=127.0.0.1 port=5432";
std::stack<pqxx::connection *> dbpool;
public:
Database(const unsigned int);

数据库.cpp:

#include "Database.hpp"
Database::Database(const unsigned int connections) {
for (int i = 0; i < connections; ++i) {
try {
auto* dbconn = new pqxx::connection(connectionString);
dbpool.emplace(dbconn);
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
}
}

main.cpp:

#include "Database.hpp"
int main(int argc, char* argv[]) {
Database database {10};
auto *D = dbpool.top();
dbpool.pop();
const std::string query = "select * from mytable";
pqxx::nontransaction N(*D);
pqxx::result R(N.exec(query));
for (pqxx::result::const_iterator c = R.begin(); c != R.end(); ++c) {
std::cout << c[1].as<std::string>() << std::endl;
};
dbpool.push(D);
}