MSVC 2017 Qt 12.3 版本下使用 mysql数据库 8.18版本的
刚开始一切都是美好的,突然有一天客户的新需求来了,需要依赖数据库查询的结果。然后啊,喷出来下面的崩溃信息
query error = "Lost connection to MySQL server during query QMYSQL: Unable to execute query"
select error "MySQL server has gone away QMYSQL: Unable to execute query"
没办法呀!在现场遇到这种棘手的,让人不明所以的问题,还真是让人崩溃
后来自己写了类似的demo发现确实能机会100%再现上面崩溃的问题。
我是在循环体中先执行查询,然后更加业务来确认是插入还是更新数据库(插入是异步的其他线程的),居然就会出现上述的崩溃
遇到上述问题,不知道为什么会这样。按照道理mysql不能这么脆弱才对呀!但是啊,项目紧急,客户临门,急于星火呀!
于是乎,想到了第一个办法,既然不能嵌套那就不嵌套吧,查询和插入分离,做完了查询我存储结果然后执行插入操作
第二天按照这种思路改好了,貌似是好了。
再过了一段时间后由于数据量大了,导致查询变慢了,异步的插入还是可能和下一次的查询嵌套进来。不定时的崩溃
还是报上述的崩溃信息。
为了使得查询变快,那就加索引吧,听说索引加得好,那查询的速度可能的差别就是兰博基尼和人力三轮车的差别
为了完全分离查询和插入,再次了解了一下事务操作,看了下Qt的介绍
QSqlDatabase::database().transaction(); QSqlQuery query; query.exec("SELECT id FROM employee WHERE name = ‘Torild Halvorsen‘"); if (query.next()) { int employeeId = query.value(0).toInt(); query.exec("INSERT INTO project (id, name, ownerid) " "VALUES (201, ‘Manhattan Project‘, " + QString::number(employeeId) + ‘)‘); } QSqlDatabase::database().commit();
bool flag = false; if (mSqlDataBase.driver()->hasFeature(QSqlDriver::Transactions)) { // 先判断该数据库是否支持事务操作 qDebug()<<"will support Transactions"; if (mSqlDataBase.transaction()) // 启动事务操作 { QSqlQuery query(mSqlDataBase); QString cmd = QString("select %1 from %2 %3").arg(columns).arg(tableName).arg(condition); flag = query.exec(cmd); flag = query.exec(QString("select %1 from %2 %3").arg(columns).arg(tableName).arg("where qrInfo = \‘DLC2015\‘")); if (!mSqlDataBase.commit()) { qDebug() <<"sql commit error "<<QSqlDatabase::database().lastError(); // 提交 if (!mSqlDataBase.rollback()) { mDebug("sqlCommit error will rollBack"); qDebug() << QSqlDatabase::database().lastError(); // 回滚 } flag = false; } else { flag = true; } } } return flag;
于是将插入操作都一次性放到事务中了,终于改完之后没看见崩溃了。老实说,这个问题也不太清楚根本原因是什么。