I have a singleton class for managing database access from multiple threads. The class has to meet the following requirements:
- There can be simultaneous read operations, but writing has to be exclusive (no other writes or reads).
- A single connection should be reused for multiple queries (within a thread).
- Each thread needs to have it's own connection to the database.
- The interface should not reveal implementation details and only expose access to resources (so the client is not aware whether it's working with a database, files or memory)
My current solution uses QReadWriteLock which takes care of synchronization, however all threads are using a single database connection, which is not safe. Below is a simplified version.
class ResourceManager
{
public:
bool initialize(const QString& databasePath);
bool shutdown();
static ResourceManager& get()
{
static ResourceManager instance;
return instance;
}
QByteArray getResource(int resourceId)
{
QReadLocker locker(m_lock);
QSqlQuery query(m_db);
// ...
}
bool setResource(int resourceId, QByteArray data)
{
QWriteLocker locker(m_lock);
QSqlQuery query(m_db)
// ...
}
private:
QSqlDatabase m_db;
QReadWriteLock m_lock;
}
My idea is to implement some kind of connections cache, like the following:
QHash<ThreadHandle, QString> m_connectionCache; // thread handle - connection name
// then
if (!m_connectionCache[QThread::currentThread]) // Create new connection
QSqlQuery query(m_connectionCache[QThread::currentThread]);
The problem here is that I can't think of a good clean-up mechanism which would get rid of connections which are no longer needed, so the map will keep growing up with every new thread.
Does it seem like a good idea? Any other suggestions?
Aucun commentaire:
Enregistrer un commentaire