Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED] SQLite transactions in multiple threads
Forum Update on Monday, May 27th 2025

[SOLVED] SQLite transactions in multiple threads

Scheduled Pinned Locked Moved General and Desktop
5 Posts 4 Posters 18.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    marcus.fr
    wrote on 12 Jan 2013, 19:30 last edited by
    #1

    Hi

    Currently I'm using QSqlDatabase::transaction() and QSqlDatabase::commit() to optimize the write operations to a database. Still on large amount of queries the GUI is blocked. So I want to make some of the transactions in a secondary thread.

    According to "http://qt-project.org/doc/qt-4.8/threads-modules.html#threads-and-the-sql-module":http://qt-project.org/doc/qt-4.8/threads-modules.html#threads-and-the-sql-module that will be thread-safe if I create and use another database connection in the secondary thread. I have two questions on this:

    1. Does it mean that I can use another connection in a secondary thread to the work on the same database file? I suppose that SQLite internally will take care of a situation when 2 threads try to modify the same database file/table, but I'm not sure.

    2. Can I use QSqlDatabase::transaction() and QSqlDatabase::commit() concurrently in different threads, using different database connections but to the same database file/table? What confuses me is the note in http://qt-project.org/doc/qt-4.8/qsqldatabase.html#commit.

    I'm asking this because I want to have two database connections, one in the GUI thread (for the QSqlTableModel) and one in a secondary thread (for writing large queries).

    Thanks

    1 Reply Last reply
    0
    • M Offline
      M Offline
      MuhamedAuda
      wrote on 13 Jan 2013, 05:30 last edited by
      #2

      bq. Currently I’m using QSqlDatabase::transaction() and QSqlDatabase::commit() to optimize the write operations to a database. Still on large amount of queries the GUI is blocked. So I want to make some of the transactions in a secondary thread.

      Note: For some databases, the commit will fail and return false if there is an active query using the database for a SELECT. Make the query "inactive":http://qt-project.org/doc/qt-4.8/qsqlquery.html#isActive before doing the commit.

      1 Reply Last reply
      0
      • V Offline
        V Offline
        vidar
        wrote on 13 Jan 2013, 14:38 last edited by
        #3

        I have not done much with Sqlite yet, but I assume that (when using Sqlite) using two threads for committing data will not really speed up the transactions ...
        "Multiple processes can have the same database open at the same time. Multiple processes can be doing a SELECT at the same time. But only one process can be making changes to the database at any moment in time, however."

        1 Reply Last reply
        0
        • V Offline
          V Offline
          vidar
          wrote on 13 Jan 2013, 14:49 last edited by
          #4

          P.S.
          1+2) yes & yes. but it will probably not speed up your app as much as you might have expected.

          1 Reply Last reply
          0
          • Z Offline
            Z Offline
            Zarko Markovic
            wrote on 13 Jan 2013, 15:50 last edited by
            #5

            Transactions are not really safe in multi-threading environment. You will need to make them safe manually.

            See below how QSqlLiteDriver implements the transactions:
            @bool QSQLiteDriver::beginTransaction()
            {
            if (!isOpen() || isOpenError())
            return false;

            QSqlQuery q(createResult());
            if (!q.exec(QLatin1String("BEGIN"))) {
                setLastError(QSqlError(tr("Unable to begin transaction"),
                                       q.lastError().databaseText(), QSqlError::TransactionError));
                return false;
            }
            return true;
            

            }@

            Qt starts the transaction in the default mode which is DEFERRED. To use transactions by multiple threads one should use "BEGIN IMMEDIATE TRANSACTION". Read more in: http://www.sqlite.org/lang_transaction.html

            This means that you need to make your own functions for transactions which will use the IMMEDIATE type, then use only this type whenever you make transactions in your app. Unfortunately you can not longer use QSqlTableModel safely because it will use the default transaction mode, unless you subclass and implement SQL operations manually.

            1 Reply Last reply
            0

            4/5

            13 Jan 2013, 14:49

            • Login

            • Login or register to search.
            4 out of 5
            • First post
              4/5
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved