5. 数据库连接池实现

news2024/11/25 10:03:08

WebServer 类中的 sql_pool() 方法,用于初始化数据库连接池并设置用户数据。

void WebServer::sql_pool()
{
    /* 初始化数据库连接池 */
    m_connPool = connection_pool::GetInstance();
    m_connPool->init("localhost", m_user, m_passWord, m_databaseName, 3306, m_sql_num, m_close_log);

    /* 初始化数据库读取表 */
    users->initmysql_result(m_connPool);
}

数据库连接池

connection_pool

sql_connection_pool.h中的connection_pool 类实现了一个 数据库连接池,用于管理数据库连接。它采用了 单例模式 来确保连接池在整个程序运行期间只有一个实例。

设置数据库连接池的目的是为了提高性能和减少数据库连接建立和销毁的开销

  1. GetInstance():实现单例模式,通过静态成员函数获取唯一的连接池实例。
  2. 使用信号量 reserve 控制连接的获取和释放,确保线程在连接不可用时会阻塞,直到有可用连接。
  3. 使用 互斥锁 用于多线程同步,保护对 connList 和连接计数器的操作,确保线程安全。
  4. 使用 std::list<std::shared_ptr<MYSQL>> 来保存连接池中的所有数据库连接。shared_ptr 用于自动管理连接的生命周期,确保资源在适当时被释放。
  5. connectionRAII 实现了 RAII(资源获取即初始化) 的模式,用于自动管理数据库连接的获取和释放。

connectionRAII

connectionRAII 类是一个典型的 RAII 模式实现,用于管理数据库连接的生命周期。它的作用是确保从连接池中获取的数据库连接能够在使用结束后自动释放,从而防止资源泄漏。保证每次从连接池中获取的连接在使用后都被正确归还。通过 RAII 模式,数据库连接的生命周期与 connectionRAII 对象绑定,确保不会有连接被无意遗忘。

这样设计的目的

数据库连接池的目的是为了管理数据库连接的复用,避免数据库连接频繁创建和销毁带来的额外开销,在一个多线程的应用程序中,数据库操作非常频繁,每次都建立和销毁数据库连接会带来较大的性能开销。使用 connection_pool 可以有效提高连接复用率,减少连接的开销。

RAII 机制的目的就是确保数据库连接能够安全的获取和归还。

例如,在一个 HTTP 服务器中处理客户端请求时,每个请求可能都需要访问数据库。使用 connectionRAII 可以确保每个请求在需要时从连接池中获取一个连接并在请求处理完毕后自动归还,从而提升服务器的并发性能和资源利用率。

改进

  1. 使用mysql_error() 提供的具体错误描述:
LOG_ERROR("MySQL init Error: %s", mysql_error(raw_con));
  1. 在创建多个连接的过程中,如果某个连接创建失败,原来的代码会直接退出exit(1);,导致所有已成功创建的连接也会被释放。
    改进: 考虑使用逐步回滚的方式来处理这种情况。 如果一个连接创建失败,可以先释放已经创建的连接,但是不退出程序。
for (int i = 0; i < MaxConn; i++)
{
    MYSQL *con = NULL;
    con = mysql_init(con);		/* 初始化 MYSQL 连接句柄 */

    if (con == NULL)
    {
        LOG_ERROR("MySQL init Error: %s", mysql_error(con));

        continue;  				/* 记录错误但不退出程序 */ 
    }

    /* 连接到数据库 */
    con = mysql_real_connect(con, url.c_str(), User.c_str(), PassWord.c_str(), DBName.c_str(), Port, NULL, 0);

    if (con == NULL)
    {
        LOG_ERROR("MySQL init Error: %s", mysql_error(con));
        mysql_close(con);  		/* 释放当前连接资源 */
        continue;  				/* 记录错误但不退出程序 */
    }

    connList.push_back(con);	/* 将连接加入连接池 */
    ++m_FreeConn;				/* 增加空闲连接计数 */
}

/* 如果没有任何连接被成功创建 */ 
if (m_FreeConn == 0)
{
    LOG_ERROR("All database connections failed to initialize.");
    exit(1);  					/* 没有连接被创建成功,退出程序 */
}  
  1. 使用智能指针std::shared_ptr 来管理 MYSQL 连接 。std::shared_ptr 可以被多个对象共享,同时它会在最后一个持有者销毁时释放资源。
    改进:
    • 使用 std::shared_ptr<MYSQL> 替代原来的裸指针 MYSQL*
    • 将连接池的 connList 修改为存储 std::shared_ptr<MYSQL> 的列表。
  2. 原来的获取可用连接函数,如果数据库连接池为空,直接返回 null
MYSQL *connection_pool::GetConnection()
{
	MYSQL *con = NULL;

	if (0 == connList.size())
		return NULL;

	// ...
}

这样会导致返回一个无效的数据库连接,改进:使用信号量阻塞等待,直到连接池中存在可用连接。

std::shared_ptr<MYSQL> connection_pool::GetConnection()
{	
	reserve.wait();   				/* 阻塞等待信号量,确保有可用连接 */

	lock.lock();

	if (connList.empty())
    {
        lock.unlock();
        return nullptr;
    }

	std::shared_ptr<MYSQL> con = connList.front();
	connList.pop_front();

	--m_FreeConn;
	++m_CurConn;

	lock.unlock();

	return con;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2228698.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity BesHttp插件修改Error log的格式

实现代码 找到插件的 UnityOutput.cs 然后按照需求替换为下面的代码即可。如果提示 void ILogOutput.Flush() { } 接口不存在&#xff0c;删除这行代码即可。 using Best.HTTP.JSON.LitJson; using System; using System.Collections.Generic; using UnityEngine; using Syst…

Kubernetes实战——DevOps集成SpringBoot项目

目录 一、安装Gitlab 1、安装并配置Gitlab 1.1 、下载安装包 1.2、安装 1.3、修改配置文件 1.4、更新配置并重启 2、配置 2.1、修改密码 2.2、禁用注册功能 2.3、取消头像 2.4、修改中文配置 2.5、配置 webhook 3、卸载 二、安装镜像私服Harbor 1、下载安装包 2、…

【移动应用开发】访问网络

目录 一、运行截图 二、源代码 1. WebView的简单使用 ① activity_main.xml ② MainActivity.kt ③ AndroidManifest.xml 2. 使用OkHttp访问以下接口&#xff0c;获取Aspirin化合物的JSON格式数据 ① activity_okhttp.xml ② OKhttpActivity ③ 导入依赖 3. 使用GSO…

软件工程--需求分析与用例模型

面向对象分析(ObjectOrientedAnalysis&#xff0c;简称OOA) 分析和理解问题域&#xff0c;找出描述问题域所需的类和对象&#xff0c;分析它们的内部构成和外部关系&#xff0c;建立独立于实现的OOA模型&#xff0c;暂时忽略与系统实现有关的问题。 主要使用UML中的以下几种图…

Android中同步屏障(Sync Barrier)介绍

在 Android 中&#xff0c;“同步屏障”&#xff08;Sync Barrier&#xff09;是 MessageQueue 中的一种机制&#xff0c;允许系统临时忽略同步消息&#xff0c;以便优先处理异步消息。这在需要快速响应的任务&#xff08;如触摸事件和动画更新&#xff09;中尤为重要。 在 An…

MyBatis-Plus:简化 CRUD 操作的艺术

一、关于MyBatis-Plus 1.1 简介 MyBatis-Plus 是一个基于 MyBatis 的增强工具&#xff0c;它旨在简化 MyBatis 的使用&#xff0c;提高开发效率。 ​ ‍ ‍ ‍ ​ ‍ 关于Mybatis 简介 MyBatis 是一款流行的 Java 持久层框架&#xff0c;旨在简化 Java 应用程序与数…

ECharts饼图-圆角环形图,附视频讲解与代码下载

引言&#xff1a; 在数据可视化的世界里&#xff0c;ECharts凭借其丰富的图表类型和强大的配置能力&#xff0c;成为了众多开发者的首选。今天&#xff0c;我将带大家一起实现一个饼图图表&#xff0c;通过该图表我们可以直观地展示和分析数据。此外&#xff0c;我还将提供详…

正则表达式匹配日期格式

前言 这里有sql文本&#xff0c;是从数据库中拷贝出来的&#xff0c;希望重新执行的时候createTime和updateTime都统一设置成当前日期。 利用正则表达式结合文本编辑器&#xff0c;就能全局替换了 (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) 替换结果如下

学习伊圣雨老师的 epoll 编程

&#xff08;1&#xff09;书里提出了疑问&#xff0c;epoll 函数的工作方式&#xff0c;区分为水平触发与边缘触发 &#xff1a; &#xff08;2&#xff09; 谢谢

3.2K+ Star!OpenLLMetry:一个开源的LLM应用可观测性工具

OpenLLMetry 简介 OpenLLMetry[1] 是一个基于OpenTelemetry的开源可观测性工具&#xff0c;专为LLM&#xff08;Large Language Models&#xff0c;大型语言模型&#xff09;应用设计。 它提供了一套扩展&#xff0c;可以帮助开发者全面监控和管理他们的LLM应用。 项目特点 主…

C# 编程语言学习教程

C# 编程语言学习教程 目录 C# 简介 1.1 什么是 C#1.2 C# 的特点1.3 C# 的应用领域 环境搭建 2.1 安装 Visual Studio2.2 创建第一个 C# 项目 基础语法 3.1 数据类型3.2 控制结构3.3 数组与字符串 面向对象编程 4.1 类与对象4.2 继承与多态4.3 接口与抽象类 常用库与框架 5.1 .…

分类预测 | GCN图卷积神经网络多特征分类预测(MATLAB)

分类预测 | GCN图卷积神经网络多特征分类预测(MATLAB) 目录 分类预测 | GCN图卷积神经网络多特征分类预测(MATLAB)分类效果基本介绍程序设计参考资料分类效果 基本介绍 GCN图卷积神经网络多特征分类预测(MATLAB) 在图卷积神经网络(GCN)中,多特征分类

以AI赋能身份验证,Jumio助力中国企业出海

近年来&#xff0c;越来越多的中国企业开始扬帆出海积极拓展全球市场。而能够为企业出海提供各种助力的技术与解决方案&#xff0c;也成为了众多企业关注的焦点。 作为全球领先的在线身份验证和欺诈预防解决方案提供商&#xff0c;Jumio于近日在北京举办了中国媒体见面会&#…

中级 <HarmonyOS第一课>合理使用动画和转场的课后习题

天道无亲&#xff0c;常与善人。 天命人&#xff0c;战斗吧&#xff01;&#xff01;&#xff01; 来自 <HarmonyOS第一课>合理使用动画和转场的习题。 判断题 animateTo可以设置组件进行位移动画时的运动路径。❌ 单选题 模态转场不包括以下哪个类别&#xff1f; A. …

Python(包和模块)

包 定义 包是将模块以文件夹的组织形式进行分组管理的方法&#xff0c;以便更好地组织和管理相关模块。 包是一个包含一个特殊的__init__.py文件的目录&#xff0c;这个文件可以为空&#xff0c;但必须存在&#xff0c;以标识目录为Python包。 包可以包含子包&#xff08;子…

数据采集-Kepware OPCUA 服务器实现

KepserverEX OPC UA server设置 目录 KepserverEX OPC UA server设置一、OPC UA(OPC Unified Architecture)二、防火墙的配置三、配置KepserverEX的OPC UA3.1 启用远程连接3.2 启动OPCUA服务器接口 四、管理OPCUA的端口和证书4.1 添加端口4.2 证书申请 一、OPC UA(OPC Unified …

医学和生信web APP 平台- Appmatrix

医学&#xff08;和生信&#xff09;web APP 平台- Appmatrix 最近使用shinyproxy将平时所构建的shiny和streamlit医学类应用汇集在一起&#xff0c;实现一站式访问&#xff0c;另外&#xff0c;使用了自己电脑内网穿透&#xff0c;一定程度上缓解了数据分析类APP消耗计算资源…

PyTorch nn.Conv2d 空洞卷积

torch.nn.Conv2d() 中 dilation 参数控制卷积核的间隔 dilation controls the spacing between the kernel points 当 dilation1 时, 表示卷积核没有额外的空白间距, 也就是标准卷积当 dilation>1 时, 表示空洞卷积(dilated convolution) 动画演示: 手动计算 以 2*2 的卷…

大模型,多模态大模型面试问题【计算图,LLama,交叉熵,SiLU,RLHF】

大模型&#xff0c;多模态大模型面试问题【计算图&#xff0c;LLama&#xff0c;交叉熵&#xff0c;SiLU&#xff0c;RLHF】 问题一&#xff1a;讲一讲计算图中pytorch是什么&#xff0c;TensorFlow是什么&#xff1f;1. PyTorch2. TensorFlow区别总结 问题二&#xff1a;Llama…

learnopencv系列一:使用神经网络进行特征匹配(LoFTR、XFeat、OmniGlue)、视频稳定化、构建Chrome Dino游戏机器人

文章目录 一、使用神经网络进行特征匹配1.1 什么是图像特征&#xff1f;1.2 特征匹配的应用场景——为什么在2024年还要进行特征匹配&#xff1f;1.3 特征匹配——经典方法与深度学习1.3.1 经典特征匹配1.3.2 深度学习特征匹配1.3.3 XFeat1.3.3.1 网络结构1.3.3.2 局部特征提取…