树莓派开发笔记(十七):树莓派4B+上Qt多用户连接操作Mysql数据库同步(单条数据悲观锁)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 安装了mysq数据库,最终时为了实现在一个树莓派上实现多用户多进程操作的同步问题,避免数据并发出现一些错误,本篇安装了远程服务并且讲述了使用Qt进行悲观锁for update操作,命令行进行同步查询的示例。

前言

  安装了mysq数据库,最终时为了实现在一个树莓派上实现多用户多进程操作的同步问题,避免数据并发出现一些错误,本篇安装了远程服务并且讲述了使用Qt进行悲观锁for update操作,命令行进行同步查询的示例。


其他操作

  这里只是稍微提一下,具体参照博主的树莓派系列博客,非常详细。

  远程登陆界面

sudo apt-get install tightvncserver
sudo apt-get install xrdp
sudo service xrdp restart
sudo ufw allow 3389
sudo service ufw restart

  然后可以使用window远程桌面登陆了:

  默认用户名:pi

  默认密码:raspberry

  

  

安装qt5

sudo apt-get install qt5-default
sudo apt-get install qtcreator

  安装好后,远程桌面的程序里面就多了个qtcreator了:

  

  

  创建一个界面工程,然后运行:

  (编译速度比几年前的3B+快一些,后续开发过程中测试一下,是否可以忽略3B+的交叉编译)

  

  检查数据库驱动:

  

  没有mysql的数据库驱动。

sudo apt-get install libqt5sql5-mysql

  


Qt操作mariadb数据库

QSqlDatabase db;
db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("127.0.0.1");
db.setPort(3306);
db.setDatabaseName("data");
db.setUserName("root");
db.setPassword("a1234567");
if(db.open())
{
    LOG << "Succeed to open db";
}else{
    LOG << "Failed to open db:" << db.lastError().text();
    return;
}
QString cmd = "select * from student;";
QSqlQuery query = db.exec(cmd);
while(query.next())
{
    LOG << query.value(0).toString()
        << query.value(1).toString()
        << query.value(2).toString()
        << query.value(3).toString();
}

  


多用户操作

  本意是为了多用户操作,那么读的时候需要加读锁,写的时候需要加写锁。

  两个用户同时读取了数据库中的一条记录,此时用户A对其中一个字段的值进行了修改操作并进行了提交,后来用户B也对这个字段进行了修改,用户B的提交将会覆盖用户A提交的值。

  

锁类型

悲观锁

  每次去取数据,很悲观,都觉得会被别人修改,所以在拿数据的时候都会上锁。简言之,共享资源每次都只给一个线程使用,其他线程阻塞,等第一个线程用完后再把资源转让给其他线程。synchronized和ReentranLock等都是悲观锁思想的体现。

乐观锁

  每次去取数据,都很乐观,觉得不会被被人修改。因此每次都不上锁,但是在更新的时候,就会看别人有没有在这期间去更新这个数据,如果有更新就重新获取,再进行判断,一直循环,直到拿到没有被修改过的数据。(mysql需要自己实现乐观锁)。

for update使用场景(悲观锁)

  for update 可以为数据库中的一行数据加上一个排它锁。当一个事务的操作未完成时候,其他事务可以读取但是不能写入或更新。

  如果项目对某个数据准确性有要求,并且项目存在并发(不一定高并发),则需要使用 for update。

  比如:用户A使用余额购买商品,此时用户B向用户A发起转账,如果恰好处在同一时间,则可能造成用户A最终余额错误。此时需要使用 for update 进行数据加锁防止出错。

  这种情况下,即使并发很小,但是也会有一定的概率会碰到,而余额的错误即使差一分钱也是不能容忍的,所以这种特定的场景,即使不是高并发,也应该使用 for update 规避问题。

for update 用法

begin;
select * from XXX where XXX for update;
...
commit;

  for update 必须在事务中才生效。


Qt测试

使用127.0.0.1的ip进行连接(本地连接)

QSqlDatabase db;
db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("127.0.0.1");
db.setPort(3306);
db.setDatabaseName("data");
db.setUserName("root");
db.setPassword("a1234567");
if(db.open())
{
    LOG << "Succeed to open db";
}else{
    LOG << "Failed to open db:" << db.lastError().text();
    return;
}
if(db.transaction())
{
    QString cmd = "select * from student for update;";
    QSqlQuery query = db.exec(cmd);
    while(query.next())
    {
        LOG << query.value(0).toString()
            << query.value(1).toString()
            << query.value(2).toString()
            << query.value(3).toString();
    }
    for(int index = 0; index < 10; index++)
    {
        QThread::sleep(1);
        LOG << "sleep:" << index;
    }
    if(!db.commit())
    {
        LOG << "Failed to commit";
    }
}

  

  至此,我们的锁加入成功,说清楚原理可以方便大家着手开始开发多用户进程操作数据库的同步开发了。

使用局域网的ip进行连接(远程连接)

QSqlDatabase db;
db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("192.168.0.103");
db.setPort(3306);
db.setDatabaseName("data");
db.setUserName("root");
db.setPassword("a1234567");
if(db.open())
{
    LOG << "Succeed to open db";
}else{
    LOG << "Failed to open db:" << db.lastError().text();
    return;
}
if(db.transaction())
{
    QString cmd = "select * from student for update;";
    QSqlQuery query = db.exec(cmd);
    while(query.next())
    {
        LOG << query.value(0).toString()
            << query.value(1).toString()
            << query.value(2).toString()
            << query.value(3).toString();
    }
    for(int index = 0; index < 10; index++)
    {
        QThread::sleep(1);
        LOG << "sleep:" << index;
    }
    if(!db.commit())
    {
        LOG << "Failed to commit";
    }
}

  连接不上:

  

  这个时候需要修改下配置:

sudo vi /etc/mysql/mariadb.conf.d/50-server.cnf

  

  重启服务:

systemctl restart mysql.service

  

  继续测试,下面是用树莓派使用局域网ip(之前也不能连接127.0.0.1):

  

  连接成功,然后在局域网pc上连接,但是不能打开事务:

  

  修改一下:

  

  这个其实是跟mysql驱动有关系,因为笔者是几年前弄得libmysql.dll和libmysqld.dll,这个不深究了,已经可以远程操作了。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
2月前
|
存储 关系型数据库 数据库
附部署代码|云数据库RDS 全托管 Supabase服务:小白轻松搞定开发AI应用
本文通过一个 Agentic RAG 应用的完整构建流程,展示了如何借助 RDS Supabase 快速搭建具备知识处理与智能决策能力的 AI 应用,展示从数据准备到应用部署的全流程,相较于传统开发模式效率大幅提升。
附部署代码|云数据库RDS 全托管 Supabase服务:小白轻松搞定开发AI应用
|
4月前
|
关系型数据库 数据库 RDS
【瑶池数据库训练营及解决方案本周精选(探索PolarDB,参与RDS迁移、连接训练营)】(5.30-6.8)
本周精选聚焦数据库迁移训练营、快速连接云数据库RDS训练营及智能多模态搜索解决方案。为用户提供模拟教程与实战演练,学习RDS MySQL实例连接与数据管理技能,助力企业智能化发展。每周解锁数据库实战新场景,抓紧时间,精彩不容错过!
|
2月前
|
存储 SQL 前端开发
跟老卫学HarmonyOS开发:ArkTS关系型数据库开发
本节以“账本”为例,使用关系型数据库接口实现账单的增、删、改、查操作。通过创建ArkTSRdb应用,演示如何操作RdbStore进行数据管理,并结合界面按钮实现交互功能。
110 0
跟老卫学HarmonyOS开发:ArkTS关系型数据库开发
|
4月前
|
存储 缓存 自然语言处理
评论功能开发全解析:从数据库设计到多语言实现-优雅草卓伊凡
评论功能开发全解析:从数据库设计到多语言实现-优雅草卓伊凡
100 8
评论功能开发全解析:从数据库设计到多语言实现-优雅草卓伊凡
|
2月前
|
SQL XML Java
配置Spring框架以连接SQL Server数据库
最后,需要集成Spring配置到应用中,这通常在 `main`方法或者Spring Boot的应用配置类中通过加载XML配置或使用注解来实现。
228 0
|
5月前
|
Oracle 安全 关系型数据库
【Oracle】使用Navicat Premium连接Oracle数据库两种方法
以上就是两种使用Navicat Premium连接Oracle数据库的方法介绍,希望对你有所帮助!
1090 28
|
5月前
|
SQL 数据库连接 数据库
在C++的QT框架中实现SQLite数据库的连接与操作
以上就是在C++的QT框架中实现SQLite数据库的连接与操作的基本步骤。这些步骤包括创建数据库连接、执行SQL命令、处理查询结果和关闭数据库连接。在实际使用中,你可能需要根据具体的需求来修改这些代码。
273 14
|
5月前
|
SQL 调度 数据库
开发YashanDB数据库?用 DBeaver for YashanDB 更顺手
数据库开发复杂易错,尤其在企业级场景中。为提升效率,YashanDB 团队基于 DBeaver 开源工具打造专属解决方案——DBeaver for YashanDB。它支持多类型数据库对象管理(表、视图、函数等),适配 YashanDB 特有表结构(HEAP、LSC),提供智能补全、语法高亮、SQL 调试等功能,让开发更高效流畅。推荐用于数据库应用开发团队、高频调试用户及中大型企业统一工具栈场景。
|
5月前
|
SQL 数据可视化 IDE
开发数据库不想写命令?YashanDB Developer Center 帮你轻松搞定
YashanDB Developer Center(YDC)是一款可视化的数据库开发工具,专为提升数据库开发效率而设计。它通过图形化对象管理让数据库对象清晰可见,提供智能SQL编辑器支持语法高亮与自动补全,实现PL调试的图形化操作,帮助快速定位问题。此外,操作记录可追溯,多端灵活部署,适配多种场景。无论是中大型企业研发团队,还是不熟悉命令行的业务开发者,YDC都能显著优化开发体验,堪称YashanDB的“可视化IDE”。

推荐镜像

更多