Threads and database connection
In my program I create several thread. Each thread holds a database connection, it means, each thread instantiates the "database" class which allows them to work with the database.
When the first thread is "run", then all queries to the database work fine. When the second thread in "run", then all queries to the database work too, but the first thread cannot use the database anymore.
1. Is this a correct approach of having each thread a connection to the database, or should I have a general instance of a "database" and have each thread use it ?
2. If it is correct to have each thread with an instance of the "database", what could be wrong ?
Re: Threads and database connection
Re: Threads and database connection
The class that initializes the "database" class
Code:
void Client::run(){
cout << "Client thread has enter the thread execution\n";
message = new Message(this);
database = new Database(this);
message->knowDatabase(database);
if(!tcpSocket->setSocketDescriptor(_socketDescriptor))
cout << "Error - setting socket descriptor\n";
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readMessage()));
connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(clientDisconnected()));
exec();
}
The database class:
Code:
Database::Database(Client *client){
cout << "Initializing database connection\n";
_client = client;
db.setHostName("localhost");
db.setDatabaseName("infospeed");
db.setUserName("santiago");
db.setPassword("santipass");
}
void Database::connectToDatabase(){
bool ok = db.open();
if(ok)
cout << "Database connection successful\n";
else
cout << "Error connecting to the database\n";
}
connectToDatabase();
QString myQuery
("SELECT name, lastname FROM user WHERE id=\"");
myQuery += userId;
myQuery += "\" and password=\"";
myQuery += password;
myQuery += "\"";
query.next();
QString name
= query.
value(0).
toString();
QString lastName
= query.
value(1).
toString();
QString userName
= name
+ " " + lastName;
cout << "User name " << userName.toStdString() << endl;
disconnectFromDatabase();
return userName;
}
I hope this helps to solve the issue !!!
Re: Threads and database connection
Can't you use a single connection to the database for all threads?
Re: Threads and database connection
yes, I can create just one instance for the database and use it from all threads.
Is this a better approach than using one connection per thread ?
Re: Threads and database connection
No (the docs even specify you can't do it), but if it works then why not?
What is the content of disconnectFromDatabase()?
And just to make sure - are we talking Qt4 here?
Re: Threads and database connection
Quote:
Originally Posted by
probine
yes, I can create just one instance for the database and use it from all threads.
Is this a better approach than using one connection per thread ?
Well, actually you are using only one instance from all threads. Since you are sharing the connection.
If you would like to use one connection per thread you have to use a construct such as this (pseudocode, not compiled):
Code:
QString connectionName
= QLaint1String
("infospeed@");
} else {
db.setPassword("santipass");
bool ok = db.open();
if(ok)
cout << "Database connection successful\n";
else
cout << "Error connecting to the database\n";
return db;
}
}
Re: Threads and database connection
I am not quite sure if I understood.
I am not using only one instance...
I am not sharing the connection...
Each thread holds its own connection to the database... this connection is initialized in the "run" part of each thread, so the database connection should be unique for each thread.
Re: Threads and database connection
The problem as I see it is in this line
addDatabase is a static function, which implies that is does not care in which Database object it was called; and you do not specify a specific second argument, the connectionName. The defaultvalue for this argument is "QLatin1String( defaultConnection )".
This means all your database connections will have the same connectionName. Keep this in mind when you read the following warning, copied straigt from the docs:
Quote:
Warning: If you add a database with the same name as an existing database, the new database will replace the old one. This will happen automatically if you call this function more than once without specifying connectionName.
The way I read that is: as soon as your second thread initializes its database object, it will create a new default connection and delete the old one. The SqlDatabase object in the first thread will point to the old now stale connection and should thus cease to work. Which is rather consistent with your symptoms.
Changing the creation of database objects to the above mentioned method (meaning assuring that each connection/thread gets their own connectionName) should work. (Hopefully, not fully tested as I said ;-)
Re: Threads and database connection
You would typically handle this situation using some sort of database connection pool, which can manage the lifetime of your database connections for you.