簡體   English   中英

用於同步數據庫訪問的類

[英]Class for synchronization of database access

我有一個單例類來管理來自多個線程的數據庫訪問。 該課程必須符合以下要求:

  1. 可以有同時讀取操作,但寫入必須是獨占的(沒有其他寫入或讀取)。
  2. 單個連接應該重復用於多個查詢(在一個線程內)。
  3. 每個線程都需要擁有自己與數據庫的連接。
  4. 接口不應泄露實現細節,只暴露對資源的訪問(因此客戶端不知道它是否正在使用數據庫,文件或內存)

我當前的解決方案使用QReadWriteLock來處理同步,但是所有線程都使用單個數據庫連接,這是不安全的。 以下是簡化版。

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;
}

我的想法是實現某種連接緩存,如下所示:

QHash<ThreadHandle, QString> m_connectionCache; // thread handle - connection name

// then
if (!m_connectionCache[QThread::currentThread]) // Create new connection
QSqlQuery query(m_connectionCache[QThread::currentThread]);

這里的問題是我想不出一個好的清理機制可以擺脫不再需要的連接,因此地圖將隨着每個新線程不斷成長。

這看起來好主意嗎? 還有其他建議嗎?

連接可以通過其名稱訪問, 但是您將QString傳遞給QSqlQuery的構造函數,並且此字符串被視為SQL查詢,但不是連接名稱。

幸運的是, QSqlDatabase包含您需要的緩存。 它可以被QSqlDatabase :: connectionNames讀取並由QSqlDatabase :: addDatabase寫入

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM