源地址:http://blog.csdn.net/goldenhawking/article/details/10811409

彻底抛弃MFC, 全面应用Qt 已经不少时间了。除了自己看书按步就班做了十几个验证性的应用,还正式做了3个比较大的行业应用,总体感觉很好。Native C++ 下, Qt 基本是我用过的最简便的界面库了。遇到了一些问题,大都解决的很顺利,回头想想,还是有几个问题很有意思,尤其是数据库应用。这里把我的经历分享一下。

1、线程内注册与连接数据库的竞争问题

文档上对多线程下数据库应用的注意事项写的很简明,一个线程创建的 QSqlDatabase 对象和 查出来的 QSqlQuery 对象只能给本线程用(注意,是对象,不是数据库连接本身,连接本身用名字可以多线程使用),其他情况是“不支持的”。在一个需要有几个线程并发访问不同数据库的应用中,我首先试图在各个线程的起始分别以不同的名称调用  addDatabase / database 、open,但是程序偶然会崩溃,跟踪后发现,虽然Qt 声称很多方法是“线程安全”的,但是几个方法串起来,就出问题了。Qt 会动态的加载数据库的plugin, 加载 plug in 的部分,涉及到对本地库文件的管理,这一部分,出现了竞争。于是,很自然的想到在初始连接部分设置 Mutex 保护,从 addDatabase / database到 open 的部分,要保证其原子性,问题再也没有出现。

2、数据库连接意外断裂后,恢复连接的问题

在MFC 中,一旦中途TCP连接断裂,直接重新 Open 就可以了。在Qt 里,这一招不好使了。即便 调用了 close ,再次open 也是不行的。处理方法:

在检测到问题出现后,关闭连接,并 removeDatabase;   而后,不要立刻 addDatabase, 反而是要回到该连接所在的事件循环。没有详细跟源码,很可能在 removeDatabase 后的事件循环中,Qt 内部做了一些释放操作。   怎么办呢, 可以设置一个恢复定时器,比如 1分钟,重新 addDatabase,就可以啦。如果心急的话,直接显式调用processEvent() 方法强制循环。

在多线程下,注意1中的问题,需要 Mutex保护。

3、数据库插件的依赖性问题

在 Windows 下,有时我们的机器上按了好几个 Qt 版本,PATH里索性神马也不设置,依赖开发环境的继承环境适应不同的版本。这有两个问题。一是发布程序的时候,数据库驱动依赖的dll 也要与可执行文件在同一路径下发布。比如 mysql 的 dll, PostgreSQL 的依赖等。二是在集成开发环境中,这些依赖也要位于执行档文件夹下。否则,会造成虽然可以枚举到可用驱动,但是死活连接不上。调试一下就知道,原来是在路径中找不到依赖项,导致dll加载失败哦!

Qt的数据库操作自成一派,相对于复杂的 ADO \ODBC\DAO\OLEDB 等传统 C++ 访问数据库的方法,还是很先进的,充分体现了 OO 的理念。对数据库的封装,想法是很有意思的。设计者把进程内的数据库连接作为一种资源,每个连接有一个唯一的名字,可以通过全局的 addDatabase, removeDatabase, cloneDatabase 来增删,想用的时候,直接用全局的 database 来获取。这样的好处,是大大节省了开发者的负担。以前为了传递一个数据库连接的变量,必须在很多方法入库处添加指向这个变量的指针或者引用,有时候不得不在对象的属性中加入静态的变量,来记录这个连接。现在,什么时候想用,给个名字就可以了,不需要传递。当然,文档说的是比较简化的,至少有两点要注意,

1)这些增删方法号称是线程安全的,但是,在实际应用中,还是要注意用 Mutex 保护全局创建流程,或者,重载这些函数,创建自己的安全版本。

2)一个线程创建的数据库对象(如 addDatabase 的返回值)只能在同一线程使用,但是,addDatabase 注册的连接(名字是开发者定)可以跨线程使用,唯一需要注意的是,在调用全局方法的时候,要有原子保护。

Qt 多线程与数据库操作需要注意的几点问题的更多相关文章

  1. Qt 多线程与数据库操作需要注意的几点问题(QSqlDatabase对象只能在当前线程里使用)

    彻底抛弃MFC, 全面应用Qt 已经不少时间了.除了自己看书按步就班做了十几个验证性的应用,还正式做了3个比较大的行业应用,总体感觉很好.Native C++ 下, Qt 基本是我用过的最简便的界面库 ...

  2. qt 5 数据库操作(mysql)

    其实大家都知道,QT5以上的都自带了数据库驱动,所以呢,基本上可以直接使用,于是如果想知道怎么连接数据库,请参考这位大神写的.http://qtdebug.com/DB-AccessMySQL.htm ...

  3. 【转载】QT MySQL数据库操作总结

    转载自http://blog.chinaunix.net/uid-28194872-id-3631462.html #include <QtSql> QT += sqlQSqlDataba ...

  4. Qt: 数据库操作;

    QT的数据库操作有两种方式: 一) 使用QsqlTableModel类, 可以配合QTableView进行界面显示并进行数据库操作, 这种方法比较方便快捷: 二)  使用原始SQL语言, 利用INSE ...

  5. 界面编程之QT的数据库操作20180801

    /*******************************************************************************************/ 一.数据库连 ...

  6. Qt 学习之路 2(55):数据库操作

    Qt 提供了 QtSql 模块来提供平台独立的基于 SQL 的数据库操作.这里我们所说的“平台独立”,既包括操作系统平台,又包括各个数据库平台.另外,我们强调了“基于 SQL”,因为 NoSQL 数据 ...

  7. qt 数据库操作总结

    #include <QtSql>QT += sql QSqlDatabase类实现了数据库连接的操作QSqlQuery类用来执行SQL语句QSqlRecord类 封装数据库所有记录 第一: ...

  8. qt sql 数据库操作

    1.  连接数据库 mysql连接: QSqlDatabase mysql_db=QSqlDatabase::addDatabase("QMYSQL","mysql_co ...

  9. [R语言]R语言使用多线程对数据库进行大批量访问时出现无法连接问题

    问题描述: 在R中使用多线程对数据库进行写入,在服务器端运行脚本(linux环境),总是在第6-7万个任务线程时,出现无法连接到数据库的问题.任务中断,错误信息为task 6xxxx failed,C ...

随机推荐

  1. hdu1867之KMP

    A + B for you again Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  2. 五毛的cocos2d-x学习笔记01-创建项目

    终于准备开始学习cocos2d-x了.因为想和同学一起做游戏参加比赛,所以打算学习很热的Cocos2d-x.因为已经学习了C++,所以我想入门应该不是很困难.再加上官网有中文教程以及多不胜数的游戏开发 ...

  3. BZOJ 1613: [Usaco2007 Jan]Running贝茜的晨练计划( dp)

    dp乱搞即可...( 我就是这样 A 的.. 后来想改快一点..然后就WA了...不理了 ------------------------------------------------------- ...

  4. UltraEdit中java代码换行问题

    在很多开发中始用的文本编辑器中UltraEdit是非常主流的种了,但是,随着版本的更新,最近几版中出现了以下问题 问题描述:当用UltraEd(14.0版本)编写Java代码时,当遇到{}换行时,希望 ...

  5. Centon6.5虚拟机桥接设置

    参考资料:http://blog.csdn.net/iamfafa/article/details/6209009 安装虚拟机的时候 就直接选择桥接,可以直接 使用 查看此状态下的配置如下 : 虚拟环 ...

  6. 监测scroll

    $(window).scroll(function() { var scrollValue = $(this).scrollTop(); var h=200+scrollValue; $('.yui3 ...

  7. python 安装ssh和Scrapy

    在Python中没有专用的SSH模块,这需要手动的安装模块才行.Python中使用SSH需要用到OpenSSH,而OpenSSH依赖于paramiko模块,paramiko模块又依赖于pycrypto ...

  8. StringIO模块字符串的缓存

    StringIO经常被用来作为字符串的缓存,应为StringIO有个好处,他的有些接口和文件操作是一致的,也就是说用同样的代码,可以同时当成文件操作或者StringIO操作.比如: import st ...

  9. Android 使用动态载入框架DL进行插件化开发

    如有转载,请声明出处: 时之沙: http://blog.csdn.net/t12x3456    (来自时之沙的csdn博客) 概述: 随着应用的不断迭代.应用的体积不断增大,项目越来越臃肿,冗余添 ...

  10. 【Android 多媒体开发】 MediaPlayer 状态机 接口 方法 解析

    作者 : 韩曙亮 转载请著名出处 :  http://blog.csdn.net/shulianghan/article/details/38487967 一. MediaPlayer 状态机 介绍 ...