crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

> QIBASE + транзакции, не возможно выполнить более одного раза
Litkevich Yuriy
  опции профиля:
сообщение 18.3.2010, 20:42
Сообщение #1


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Тут порешал для работы с Firebird'ом воспользоваться драйвером QIBASE, до этого работал через QODBC.
Наткнулся на проблему, более одного раза (!) не могу воспользоваться транзакцией. Выжимка из кода:
model->database().transaction();
model->submitAll();
model->database().commit();
такой код почему-то срабатывает только один раз, если его вызвать повторно, то на model->submitAll() возникает ошибка.
В Qt 4.4.3:
"QSqlError(-901, "Unable to execute query", "Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements")"

В Qt 4.6.0:
"QSqlError(-901, "Unable to execute query", "invalid transaction handle (expecting explicit transaction start)")"

Без транзакций всё работает как в аптеке, а также с транзакциями через QODBC.
Пробовал какую-то не свежую версию QFirebird, которую выкладывал один человек на прогорге, они просто падает на первой же транзакции (model->submitAll())

Может кто-нибудь просветить в чём проблема?

Окружение
Firebird - 2.1.2.18118
Windows 2000 SP4
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
 
Начать новую тему
Ответов
Litkevich Yuriy
  опции профиля:
сообщение 19.3.2010, 13:12
Сообщение #2


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Собрал свежий драйвер QFIREBIRD, транзакция тоже выполняется только один раз. Я уже начинаю подозревать, что я где-то делаю через одно место, но в упор не вижу где. Вот тестовый код:
(вставляет 10 строк)
#include <QCoreApplication>
#include <QSqlTableModel>
#include <QSettings>
#include <QSqlDatabase>
#include <QDebug>
#include <QSqlError>

bool connectToDatabse(QSettings &s)
{
    QSqlDatabase database;
    
    QString key;
    s.beginGroup("Database");
    key = "Driver";
    if (s.contains(key)){
        database = QSqlDatabase::addDatabase(s.value(key).toString());
    }else{
        qDebug() << "Key" << key << "is absent";
        return false;
    }
    key = "DbName";
    if (s.contains(key)){
        database.setDatabaseName(s.value(key).toString());
    }else{
        qDebug() << "Key" << key << "is absent";
        return false;
    }
    key = "UserName";
    if (s.contains(key)){
        database.setUserName(s.value(key).toString());
    }else{
        qDebug() << "Key" << key << "is absent";
        return false;
    }
    key = "UserPassword";
    if (s.contains(key)){
        database.setPassword(s.value(key).toString());
    }else{
        qDebug() << "Key" << key << "is absent";
        return false;
    }
    s.endGroup();


    
    if (!database.open())
    {
        QString qerr = database.lastError().text();
        qDebug() << "Error on open DB, reson:"
                 << qerr;
        return false;
    }
    qDebug() << database;
    return true;
}

//---------------------------------------------------------------------
int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    
    // Читаем настройки БД из INI-файла
    QSettings s("settings.ini", QSettings::IniFormat);
    if (!connectToDatabse(s))
        return 1;
    
    // Информация о таблице
    QString table("entities");
    table = table.toUpper();
    const int columnForInsert = 2;    

    QSqlTableModel *model = new QSqlTableModel();

    model->setTable(table);
    model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    model->select();
    
    const int rowForInsert = 10;
    int cnt = 0;
    
    while (cnt < rowForInsert){
        QString value = QString("testInsert-%1").arg(cnt);
        qDebug() << value;
        cnt++;
        //-- вставляем пустую строку в модель
        int row = model->rowCount();
        if (!model->insertRow(row)){
            qDebug() << "\t" << "Insert to model - ERROR, reson:" << model->lastError();
            return 1;
        }
        //-- вставляем данные в модель
        QModelIndex insertIndex = model->index(row, columnForInsert);
        model->setData(insertIndex, value);
        
        //-- фиксируем данные в БД
        if (model->database().transaction()){
            qDebug() << "\t" << "transaction - START";
        }else{
            qDebug() << "\t" << "transaction -" << model->database().lastError();
        }
        //
        if (model->submitAll()){
            qDebug() << "\t" << "submit - Ok";
        }else{
            qDebug() << "\t" << "submit - " << model->lastError();
        }
        //
        if (model->database().commit()){
            qDebug() << "\t" << "transaction - COMMIT";
        }else{
            qDebug() << "\t" << "transaction -" << model->lastError();
        }
    }
    return 0;
}
Может кто-то ткнёт носом?
Вот вывод:
для QODBC/Qt 4.4.3
QSqlDatabase(driver=""QODBC"", database=""UNITEST"", host="""", port=-1, user=""NNN"", open=true)
"testInsert-0"
         transaction - START
         submit - Ok
         transaction - COMMIT
"testInsert-1"
         transaction - START
         submit - Ok
         transaction - COMMIT
"testInsert-2"
         transaction - START
         submit - Ok
         transaction - COMMIT
"testInsert-3"
         transaction - START
         submit - Ok
         transaction - COMMIT
"testInsert-4"
         transaction - START
         submit - Ok
         transaction - COMMIT
"testInsert-5"
         transaction - START
         submit - Ok
         transaction - COMMIT
"testInsert-6"
         transaction - START
         submit - Ok
         transaction - COMMIT
"testInsert-7"
         transaction - START
         submit - Ok
         transaction - COMMIT
"testInsert-8"
         transaction - START
         submit - Ok
         transaction - COMMIT
"testInsert-9"
         transaction - START
         submit - Ok
         transaction - COMMIT

D:\tempData\Qt-test-18>
реально вставляются в БД все 10 записей
для QIBASE/Qt 4.4.3
D:\tempData\Qt-test-18>ee.d
QSqlDatabase(driver=""QIBASE"", database=""L:/Repository/universalDB/db/UNIVERSALDB_1_test.FDB"", host="""", port=-1, user=""NNN"", open=true)
"testInsert-0"
         transaction - START
         submit - Ok
         transaction - COMMIT
"testInsert-1"
         transaction - START
         submit -  QSqlError(-901, "Unable to execute query", "Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements")
         transaction - COMMIT
"testInsert-2"
         transaction - START
         submit -  QSqlError(-901, "Unable to execute query", "Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements")
         transaction - COMMIT
"testInsert-3"
         transaction - START
         submit -  QSqlError(-901, "Unable to execute query", "Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements")
         transaction - COMMIT
"testInsert-4"
         transaction - START
         submit -  QSqlError(-901, "Unable to execute query", "Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements")
         transaction - COMMIT
"testInsert-5"
         transaction - START
         submit -  QSqlError(-901, "Unable to execute query", "Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements")
         transaction - COMMIT
"testInsert-6"
         transaction - START
         submit -  QSqlError(-901, "Unable to execute query", "Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements")
         transaction - COMMIT
"testInsert-7"
         transaction - START
         submit -  QSqlError(-901, "Unable to execute query", "Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements")
         transaction - COMMIT
"testInsert-8"
         transaction - START
         submit -  QSqlError(-901, "Unable to execute query", "Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements")
         transaction - COMMIT
"testInsert-9"
         transaction - START
         submit -  QSqlError(-901, "Unable to execute query", "Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements")
         transaction - COMMIT
QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.

D:\tempData\Qt-test-18>
реально вставляется в БД толкько 1 запись
для qtfirebirdibppsqldriver trunk@9
QSqlDatabase(driver=""QFIREBIRD"", database=""L:/Repository/universalDB/db/UNIVERSALDB_1_test.FDB"", host="""", port=-1, user=""NNN"", open=true)
"testInsert-0"
         transaction - START
         submit - Ok
         transaction - COMMIT
"testInsert-1"
         transaction - START
*** IBPP::LogicException ***
Context: Statement::Execute
Message: No statement has been prepared.


         submit -  QSqlError(-1, "Unable execute statement", "*** IBPP::LogicException ***
Context: Statement::Execute
Message: No statement has been prepared.

")
         transaction - COMMIT
"testInsert-2"
         transaction - START
*** IBPP::LogicException ***
Context: Statement::Execute
Message: No statement has been prepared.


         submit -  QSqlError(-1, "Unable execute statement", "*** IBPP::LogicException ***
Context: Statement::Execute
Message: No statement has been prepared.

")
         transaction - COMMIT
"testInsert-3"
         transaction - START
*** IBPP::LogicException ***
Context: Statement::Execute
Message: No statement has been prepared.


         submit -  QSqlError(-1, "Unable execute statement", "*** IBPP::LogicException ***
Context: Statement::Execute
Message: No statement has been prepared.

")
         transaction - COMMIT
"testInsert-4"
         transaction - START
*** IBPP::LogicException ***
Context: Statement::Execute
Message: No statement has been prepared.


         submit -  QSqlError(-1, "Unable execute statement", "*** IBPP::LogicException ***
Context: Statement::Execute
Message: No statement has been prepared.

")
         transaction - COMMIT
"testInsert-5"
         transaction - START
*** IBPP::LogicException ***
Context: Statement::Execute
Message: No statement has been prepared.


         submit -  QSqlError(-1, "Unable execute statement", "*** IBPP::LogicException ***
Context: Statement::Execute
Message: No statement has been prepared.

")
         transaction - COMMIT
"testInsert-6"
         transaction - START
*** IBPP::LogicException ***
Context: Statement::Execute
Message: No statement has been prepared.


         submit -  QSqlError(-1, "Unable execute statement", "*** IBPP::LogicException ***
Context: Statement::Execute
Message: No statement has been prepared.

")
         transaction - COMMIT
"testInsert-7"
         transaction - START
*** IBPP::LogicException ***
Context: Statement::Execute
Message: No statement has been prepared.


         submit -  QSqlError(-1, "Unable execute statement", "*** IBPP::LogicException ***
Context: Statement::Execute
Message: No statement has been prepared.

")
         transaction - COMMIT
"testInsert-8"
         transaction - START
*** IBPP::LogicException ***
Context: Statement::Execute
Message: No statement has been prepared.


         submit -  QSqlError(-1, "Unable execute statement", "*** IBPP::LogicException ***
Context: Statement::Execute
Message: No statement has been prepared.

")
         transaction - COMMIT
"testInsert-9"
         transaction - START
*** IBPP::LogicException ***
Context: Statement::Execute
Message: No statement has been prepared.


         submit -  QSqlError(-1, "Unable execute statement", "*** IBPP::LogicException ***
Context: Statement::Execute
Message: No statement has been prepared.

")
         transaction - COMMIT
QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.

D:\tempData\Qt-test-18>

реально вставляется в БД толкько 1 запись
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Сообщений в этой теме


Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 24.4.2024, 5:49