找回密码
 立即注册
收起左侧

求教,怎样用多线程怎样向MYSQL数据库中写入数据

2
回复
7743
查看
[复制链接]
累计签到:8 天
连续签到:1 天
来源: 2014-6-6 16:43:59 显示全部楼层 |阅读模式
8Qter豆
多线程怎样向MYSQL数据库中写入数据,弄了几天还没弄好,要疯了。再此向大侠们请教 !!
真的很急,因为在最近在开发这个程序!
#include <QCoreApplication>
#include "thread.h"
#include <QVector>#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QVector<Thread*> vector;    Thread *thread;
    //创建多个线程,并start
    for(int i=0;i<10;i++){
        thread=new Thread;
        vector.append(thread);
       thread->set(i);
        thread->start();
    }
    //等待所有线程执行完,然后删除线程
    foreach(thread,vector){
        thread->wait();
    }
   foreach(thread,vector){
        delete thread;
    }
    return a.exec();
}

-------------------------------------------------------------------------------------------------

#include "thread.h"

Thread::Thread(QObject *parent) :    QThread(parent)
{
}
void Thread::run()
{
    begin();
}

//为每个线程创建一个连接名
void Thread::set(int a)
{
    connectionName=QString::number(a);
}

void Thread::connectionDatabase(QString dbName)
{
    QSqlDatabasedb=QSqlDatabase::addDatabase("QMYSQL",connectionName);
    db.setHostName("localhost");
    db.setDatabaseName(dbName);
    db.setUserName("root");
    db.setPassword("");

    if(!db.open())
       qDebug()<<"db open fail";
}

void Thread::begin()
{
    QString dbName="learnsql";
    connectionDatabase(dbName);

    QSqlDatabase db=QSqlDatabase::database(connectionName);
    db.transaction();  //开启事物

    QSqlQuery query(db);

    //向表student中插入10000条数据
   for(int i=1;i<=10000;i++){
        query.exec("insert into student values(1)");
    }

    db.commit();       //提交事物}


备注:提 前已在MYSQL数据库中创建了learnsql数据库,和student表
编译执行时通过了,可却数据写不进去,不知道哪出了问题;
不管怎样,只要大侠们能告诉我怎样用多线程在MYSQL数据库中写入数据就行了

最佳答案

查看完整内容

抱歉,现在才看到这个帖子,因为最近都很少上论坛。 你这段代码写法是有问题的,某些情况下会导致程序崩溃。 原因:虽然Qt数据库很多方法是线程安全的,但是在加载数据库plugin上却不安全,会导致竞争从而崩溃。 解决:把数据库连接部分用线程同步相关方法保护起来。 下面的代码是在你的基础上修改而来。亲测可行。 Thread.hThread.cppmain.cpp ...
回复

使用道具 举报

累计签到:6 天
连续签到:1 天
2014-6-6 16:44:00 显示全部楼层
1363386323 发表于 2014-6-6 18:26
@imlison  帮帮我,怎样用多线程向MYSQL数据库中写入数据,前提是要用事物

抱歉,现在才看到这个帖子,因为最近都很少上论坛。
你这段代码写法是有问题的,某些情况下会导致程序崩溃。
原因:虽然Qt数据库很多方法是线程安全的,但是在加载数据库plugin上却不安全,会导致竞争从而崩溃。
解决:把数据库连接部分用线程同步相关方法保护起来。
下面的代码是在你的基础上修改而来。亲测可行。

Thread.h
  1. #ifndef THREAD_H
  2. #define THREAD_H

  3. #include <QThread>
  4. #include <QMutex>

  5. class Thread : public QThread
  6. {
  7.     Q_OBJECT
  8. public:
  9.     explicit Thread(QObject *parent = 0);
  10.     ~Thread();
  11.     void set(int a);

  12. protected:
  13.     void run();

  14. private:
  15.     bool connectDatabase(QString dbName);
  16.     bool begin();

  17. private:
  18.     QString connectionName;
  19.     static QMutex mutex_log;
  20.     static QMutex mutex_db;

  21. signals:

  22. public slots:

  23. };

  24. #endif // THREAD_H
复制代码
Thread.cpp
  1. #include "Thread.h"
  2. #include <QSqlDatabase>
  3. #include <QSqlDriver>
  4. #include <QSqlQuery>
  5. #include <QSqlError>
  6. #include <QMutexLocker>
  7. #include <QDebug>

  8. QMutex Thread::mutex_log;
  9. QMutex Thread::mutex_db;

  10. #define PRINT(msg) do\
  11. {\
  12.     QMutexLocker lock(&mutex_log);\
  13.     qDebug() << __FILE__ << ":" << __LINE__ << " -> " << (msg);\
  14. }while(0)

  15. Thread::Thread(QObject *parent) :
  16.     QThread(parent)
  17. {
  18. }

  19. Thread::~Thread()
  20. {
  21. }

  22. void Thread::set(int a)
  23. {
  24.     connectionName = QString::number(a);
  25. }

  26. bool Thread::connectDatabase(QString dbName)
  27. {
  28.     QMutexLocker lock(&mutex_db);
  29.     QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", connectionName);
  30.     db.setHostName("127.0.0.1");
  31.     db.setDatabaseName(dbName);
  32.     db.setUserName("root");
  33.     db.setPassword("");
  34.     if(!db.open())
  35.     {
  36.         PRINT(QString("db open fail: %1").arg(db.lastError().text()));
  37.         return false;
  38.     }
  39.     return true;
  40. }

  41. bool Thread::begin()
  42. {
  43.     QString dbName = "learnsql";
  44.     connectDatabase(dbName);
  45.     QSqlDatabase db = QSqlDatabase::database(connectionName);
  46.     if( !db.isValid() )
  47.     {
  48.         return false;
  49.     }
  50.     db.transaction();
  51.     PRINT(QString("进入事务"));
  52.     QSqlQuery query(db);
  53.     for(int i=0; i<10; ++i)
  54.     {
  55.         query.prepare("INSERT INTO student VALUES(:value)");
  56.         query.bindValue(":value",i);
  57.         if( !query.exec() )
  58.         {
  59.             PRINT(QString("query error: %1").arg(query.lastError().text()));
  60.             continue;
  61.         }
  62.     }
  63.     db.commit();
  64.     PRINT(QString("退出事务"));
  65.     return true;
  66. }

  67. void Thread::run()
  68. {
  69.     begin();
  70. }
复制代码
main.cpp
  1. #include <QCoreApplication>
  2. #include "Thread.h"
  3. #include <QVector>

  4. #define THREAD_NUM 10

  5. int main(int argc, char *argv[])
  6. {
  7.     QCoreApplication a(argc, argv);

  8.     QVector<Thread *> threads;
  9.     for(int i=0; i<THREAD_NUM; ++i)
  10.     {
  11.         Thread *thr = new Thread;
  12.         thr->set(i);
  13.         thr->start();
  14.         threads.push_back(thr);
  15.     }
  16.     foreach (Thread *thr, threads) {
  17.         thr->wait();
  18.     }
  19.     foreach (Thread *thr, threads) {
  20.         delete thr;
  21.     }
  22.     threads.clear();

  23.     qDebug("程序执行完毕");
  24.     return a.exec();
  25. }
复制代码
回复

使用道具 举报

累计签到:8 天
连续签到:1 天
2014-6-6 18:26:08 显示全部楼层
@imlison  帮帮我,怎样用多线程向MYSQL数据库中写入数据,前提是要用事物
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了