Russian Qt Forum
Ноябрь 24, 2024, 09:26 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QSqlDataBase и Thread [Решено]  (Прочитано 4165 раз)
santaclaus
Гость
« : Апрель 13, 2011, 08:11 »

Всем доброго времени суток!
Задача такая: есть приложение, нужно отделить графическую часть от части обновления данных, соответственно все что работает с БД, вынес в отдельный поток....но тут столкнулся с такими граблями - Есть 1 запрос который просто выдергивает данные, есть 2 запрос который обновляет табличку методом Update...собственно проблема такая, выдернул данные, обновил, снова выдергиваю и запрос возвращает старые данные, которые были до изменения....снова обновляю, опять запрашиваю и вижу что выводиться операция с обновленными данными на 1 шаге....и так все время, идет задержка в 1 шаг....при этом смотрю в PLSQL Developer'e там все отлично...может кто сталкивался...
вот пример кода для работы с БД:

Код:
// сам класс потока
class DBThread: public QThread {

public:
        DBThread(QObject *parent = 0);
        void run();
        void setDataToParking();
        void setOvertakeAircraft(int idMcWith, int idMcOn, int idBoardFlight);
        QSqlDatabase db;
};

// реализация класса
void DBThread::run() //создание подключения к БД
{
    Config config; // читалка настроек подключения
    db = QSqlDatabase::addDatabase("QOCI"); // подгружаю драйвер осси
    db.setUserName(config.getUser());
    db.setPassword(config.getPassword());
    db.setHostName(config.getHost());
    db.setDatabaseName(config.getDB());
    if (!db.open()){
        qDebug() << "Not open DB: " << db.lastError();
    } else qDebug() << "Open DB OK!";
   exec();
   qDebug() << "DBThread exec";
}

void DBThread::setOvertakeAircraft(int idMcWith, int idMcOn, int idBoardFlight)
{
    QSqlDatabase db = QSqlDatabase::database();
    QSqlQuery query(db);
    query.prepare("BEGIN spp.mc_core.buksir(:1, :2, :3, :4); END;"); // таким образом изменяю данные

    query.bindValue(":1", idMcWith);
    query.bindValue(":2", idMcOn);
    query.bindValue(":3", idBoardFlight);
    query.bindValue(":4", 0, QSql::Out);

    if (query.exec()){
        int i = query.boundValue(":4").toInt();
        qDebug() << "Set ok: " << i;
    } else qDebug() << "Set error: " << query.lastError().text();
    setDataToParking(); // обнавляю данные после их изменения
}

void DBThread::setDataToParking()
{
    QSqlDatabase db = QSqlDatabase::database();
    QSqlQuery query(db);
    query.prepare("select * from table(get_fltime_mc) "); // запрос данных из БД

    query.exec();

    while(query.next()){
            qDebug() << query.value(query.record().indexOf("MC_STATUS")).toString(); // вывожу значение которое меняется
    }
}


// вызов потока из графической части
MyForm::MyForm() : ui(new Ui::MyForm)
{
    DBThread *dbThread = new DBThread(/*dc->getGraphicsItemArray(),*/);
    dbThread->start();
}

Ах да, Qt 4.7, Win7 Ultimate, БД Oracle

Уже переделал что бы это был не поток, а обычный класс, все равно работает так же криво....
« Последнее редактирование: Апрель 15, 2011, 13:12 от santaclaus » Записан
twp
Гость
« Ответ #1 : Апрель 13, 2011, 12:26 »

Во-первых, методы
Код:
        void setDataToParking();
        void setOvertakeAircraft(int idMcWith, int idMcOn, int idBoardFlight);
работают в основном потоке
Во-вторых, нужно фиксировать транзакцию, чтоб данные сразу были доступны при последующей выборке данных
Записан
santaclaus
Гость
« Ответ #2 : Апрель 13, 2011, 13:12 »

Во-вторых, нужно фиксировать транзакцию, чтоб данные сразу были доступны при последующей выборке данных
это реализовано на стороне БД.

Сейчас выявил забавную вещь....просто сделал табличку куда делаю Update и Select * from ИМЯ_ТАБЛИЦЫ, все отлично....
а вот когда вместе выше описанного селекта делаю Select * from table()....получаю свою проблему.
Попробую переделать на обычный селект с указаниями таблиц. Ну и попробую решить как то проблему с конструкцией Select from table(). О результат отпишусь.
Записан
santaclaus
Гость
« Ответ #3 : Апрель 15, 2011, 13:12 »

Ребята, вопрос разрешился.

Дело оказалось таким: в потоке вызывается процедуры update данных которая стартует с помощью query.exec() и дальше запускается тут же процедура select данных которая стартует таким же методом, при этом, эти процедуры стартуют фактически одновременно что и вызывало парадокс описанный выше.

Ну вот и получается что exec() в данном случае идут не друг за другом а почти что параллельно, а так как время выполнения процедур разное вот и складывалось ощущение задержки на один шаг)

Может кому то буде полезным. ; )


Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.247 секунд. Запросов: 20.