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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Ошибка обращения к памяти при работе с БД и потоками  (Прочитано 7131 раз)
DpoHro
Гость
« : Июль 11, 2009, 00:25 »

Хочу выяснить почему возникает подобная ситуация впринципе.

У меня создается подключение с одним именем на все приложение.
Так получилось что сейчас я модифицирую код и случилось что часть работы с БД ведется не в потоке.
Происходит событие, которое запускает поток в котором выполняется несколько последовательных запросов и в это же время идут запросы в коде расположенным вне потока.
Сдается мне, что при такой одновременной работе с одним подключением к БД и кроется access violation.

Так ли это и как этого избежать?
Записан
ритт
Гость
« Ответ #1 : Июль 11, 2009, 01:06 »

!rtfm: QSqlDatabase::cloneDatabase
Записан
DpoHro
Гость
« Ответ #2 : Июль 11, 2009, 09:53 »

Так а можно наверное же делать так:
- создать подключение
- при необходимости клонировать его на один цикл операций и затем убивать клон?
Записан
ритт
Гость
« Ответ #3 : Июль 11, 2009, 15:13 »

можно
Записан
DpoHro
Гость
« Ответ #4 : Июль 11, 2009, 21:23 »

У меня за один раз выполняется довольно много ф-ций в каждой если делать клона, открывать выполнять запросы и потом убивать, корректно ли это?
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #5 : Июль 11, 2009, 22:41 »

Ты делай клона, для каждого потока, т.к. в одном потоке всё равно обращение будет по очереди.
Записан

Юра.
DpoHro
Гость
« Ответ #6 : Июль 11, 2009, 22:58 »

У меня работа идет в одном потоке в нескольких классах сразу, муторно переделывать все, вот думаю если написать так чтобы в каждой ф-ии этих классов получать клона и убивать его после отработки запросов. Но мне кажется что частое  подключение к БД в этом случае замедлит работу.
Записан
DpoHro
Гость
« Ответ #7 : Июль 11, 2009, 23:02 »

Трудно просто будет обработать все точки где нужно закрыть подключение, а закрывать надо, так как я работаю с БД которая расположена на обычном хостинге, а там имеется ограничение на количество подключений это раз и маленький таймаут, что приводит к потере подключения если его не закрывать.
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #8 : Август 09, 2009, 15:25 »

Вообще проблем с передачей подключения не должно быть и с закрытием этих подключений - идея о содержании своего подключения в каждом потоке правильная. Тем более что передавать то ничего не надо так как сам класс QSqlDatabase так устроен что с ним можно работать так:

Код
C++ (Qt)
bool CSomeClass::some_DB_func()
{
// получаем экземпляр класса БД подключения - причем можно взять подключение по умолчанию
// можно создать копию подключения по умолчанию - через функцию clone()
// можно вообще взять именованное подключение - второй параметр означает открывать соединение если оно не открыто
 
QSqlDatabase db = QSqlDatabase::database( m_sConnectionName, false );
 
// можно проверить установлено ли подключение и установить если надо (т.к. второй параметр в QSqlDatabase::database указан false)
bool b = db.open();
qDebug() << m_sOpenDatabase << b;
b = b && db.transaction();
qDebug() << m_sStartTran << b;
 
// далее можно работать с этим экземпляром, создавать на его основе запросы и др.
QSqlQuery pQuery = new QSqlQuery( db );
 
// после можно подтвердить или отменить сделанные изменения и закрыть соединение
db.commit();
db.close();
 
// при выходе за пределы видимости класс QSqlDatabase будет корректно  уничтожен причем [b]без потери ресурсов и ворнинга[/b]
}
 

Вообще QSqlDatabase is a value class. что определяет особенности работы с ним: Changes made to a database connection via one instance of QSqlDatabase will affect other instances of QSqlDatabase that represent the same connection.
Все это выдержки из офф. документации в ассистент - этот класс очень удобен и его никуда не нужно передавать - достаточно создать экземпляр в своей функции и работать!
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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