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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QIBASE + транзакции, не возможно выполнить более одного раза  (Прочитано 4433 раз)
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« : Март 19, 2010, 13:45 »

Наткнулся на проблему - не получается использовать транзакцию более одного раза при работе с Firebird 2.1 через QIBASE.
Мне нужно было осуществлять вставку данных, в разные таблицы, в одной транзакции. Напоровшись на проблему вынужден был написать тестовую программу, которая делает простую вставку в явной транзакции.
Вот код:
Код
C++ (Qt)
#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;
}
Этот код должен сделать 10 вставок в БД. Однако, делает только одну вставку, а дальше ошибки.
Возможно я не правильно что-то делаю. Именно это я и хочу сейчас выяснить есть ли в моём коде ошибка или нет.
Дополнительные подробности, результаты работы через другие драйверы, можно посмотреть тут
« Последнее редактирование: Март 19, 2010, 14:15 от lit-uriy » Записан

Юра.
Troglodit
Гость
« Ответ #1 : Март 19, 2010, 14:48 »

imho это просто не понятно зачем использовать в этом случает QSqlTableModel?
QSqlQuery и prepare вам ускорит выполнение в разы.
Записан
Zmeishe
Гость
« Ответ #2 : Март 19, 2010, 15:23 »

Мне нужно было осуществлять вставку данных, в разные таблицы, в одной транзакции. Напоровшись на проблему вынужден был написать тестовую программу, которая делает простую вставку в явной транзакции.

Этот код должен сделать 10 вставок в БД. Однако, делает только одну вставку, а дальше ошибки.

В рамках одной транзакции.
1 .Старт транзакции
2. Цикл из 10 вставок
3. Подтверждение транзакции.


В рамках 10 транзакций.
0. Цикл из 10 вставок
1. Старт транзакции
2. 1 Вставка.
3. Подтверждение транзакции.

Разбираться не стал, т.к. тобой не представлены описания ошибок, которые возникают.
Похоже идёт
старт транзакции
вставка
подтверждение транзакции
снова вставка, но уже без старта транзакции





Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #3 : Март 19, 2010, 17:02 »

imho это просто не понятно зачем использовать в этом случает QSqlTableModel?
QSqlQuery и prepare вам ускорит выполнение в разы.
если читать тему внимательно, то всё понятно:
Напоровшись на проблему вынужден был написать тестовую программу, которая делает простую вставку в явной транзакции.

т.к. тобой не представлены описания ошибок, которые возникают.
я указал ссылку, чтобы множественным копипастом не заниматься:
Дополнительные подробности, результаты работы через другие драйверы, можно посмотреть тут
Записан

Юра.
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #4 : Март 21, 2010, 00:52 »

Продолжаю раскопки.
Засунув в драйвер QIBASE кучу отладки, на сегодня, выяснил только одну вещь:
Старт транзакции происходит всякий раз, с новым номером транзакции. Но, почему-то сама запись в базу (второй и последующие разы) происходит с номером транзакции, который был у первой транзакции
Записан

Юра.
gigabyte
Гость
« Ответ #5 : Март 26, 2010, 21:46 »

попробуй перейти на QFirebirdsql
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #6 : Март 27, 2010, 01:39 »

>>попробуй перейти на QFirebirdsql
пробовал
Записан

Юра.
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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