Qt多线程操作MySql数据库
步骤:
1、QSqlDatabase::addDatabase第二个参数名称要不一致。
2、QSqlDatabase::addDatabase和QSqlDatabase::open外围加锁,保证连接时不会造成数据竞争(Qt 动态加载plugin, 加载 plugin 的部分,涉及到对本地库文件的管理,出现了数据竞争)。
3、QSqlQuery(QSqlDatabase) 强制指定连接
4、连接使用完后记得删除QSqlDatabase::removeDatabase。
经过代码测试,Qt可以对mysql多线程操作。
1 void T1::Run() 2 { 3 QSqlDatabase db; 4 mutex_->lock(); 5 if(QSqlDatabase::contains("zk1")) 6 db = QSqlDatabase::database("QMYSQL", "zk1"); 7 else{ 8 db = QSqlDatabase::addDatabase("QMYSQL", "zk1"); 9 db.setHostName("127.0.0.1"); 10 db.setPort(3306); 11 db.setUserName("root"); 12 db.setPassword("zhaokai"); 13 db.setDatabaseName("t1"); 14 } 15 16 qDebug()<<QSqlDatabase::connectionNames(); 17 18 if(!db.open()) 19 qDebug()<<"T1 warning!"; 20 mutex_->unlock(); 21 QSqlQuery query(db); 22 23 QElapsedTimer timer; 24 timer.start(); 25 int count = 0; 26 db.transaction(); 27 while(count<10){ 28 QString sql = "INSERT INTO pwtest VALUES(AES_ENCRYPT('%1','zhaokai'), AES_ENCRYPT('T1','zhaokai'));"; 29 sql = sql.arg(QString::number(count)); 30 query.exec(sql); 31 count++; 32 QThread::msleep(1); // 加了1ms延时,保证数据乱序 33 qDebug()<<"t1 count = "<<count; 34 } 35 db.commit(); 36 }
1 void T2::Run() 2 { 3 QSqlDatabase db; 4 mutex_->lock(); 5 if(QSqlDatabase::contains("zk2")) 6 db = QSqlDatabase::database("QMYSQL", "zk2"); 7 else{ 8 db = QSqlDatabase::addDatabase("QMYSQL", "zk2"); 9 db.setHostName("127.0.0.1"); 10 db.setPort(3306); 11 db.setUserName("root"); 12 db.setPassword("zhaokai"); 13 db.setDatabaseName("t1"); 14 } 15 if(!db.open()) 16 qDebug()<<"T2 warning!"; 17 mutex_->unlock(); 18 QSqlQuery query(db); 19 20 query.exec("START TRANSACTION"); 21 int count = 0; 22 while(count<10){ 23 QString sql = "INSERT INTO pwtest VALUES(AES_ENCRYPT('%1','zhaokai'), AES_ENCRYPT('T2','zhaokai'));"; 24 sql = sql.arg(QString::number(count)); 25 query.exec(sql); 26 count++; 27 qDebug()<<"t2 count = "<<count; 28 } 29 query.exec("COMMIT"); 30 }