How to use SQLite in a multi-threaded application?

前端 未结 7 947
情书的邮戳
情书的邮戳 2020-11-28 02:43

I\'m developing an application with SQLite as the database, and am having a little trouble understanding how to go about using it in multiple threads (none of the other Stac

相关标签:
7条回答
  • 2020-11-28 02:57

    Check this code from the SQLite wiki.

    I have done something similar with C and I uploaded the code here.

    I hope it's useful.

    0 讨论(0)
  • 2020-11-28 03:04

    I realize this is an old thread and the responses are good but I've been looking into this recently and came across an interesting analysis of some different implementations. Mainly it goes over the strengths and weaknesses of connection sharing, message passing, thread-local connections and connection pooling. Take a look at it here: http://dev.yorhel.nl/doc/sqlaccess

    0 讨论(0)
  • 2020-11-28 03:10

    Summary

    Transactions in SQLite are SERIALIZABLE.

    Changes made in one database connection are invisible to all other database connections prior to commit.

    A query sees all changes that are completed on the same database connection prior to the start of the query, regardless of whether or not those changes have been committed.

    If changes occur on the same database connection after a query starts running but before the query completes, then it is undefined whether or not the query will see those changes.

    If changes occur on the same database connection after a query starts running but before the query completes, then the query might return a changed row more than once, or it might return a row that was previously deleted.

    For the purposes of the previous four items, two database connections that use the same shared cache and which enable PRAGMA read_uncommitted are considered to be the same database connection, not separate database connections.


    In addition to the above information on multi-threaded access, it might be worth taking a look at this page on isolation, as many things have changed since this original question and the introduction of the write-ahead log (WAL).

    It seems a hybrid approach of having several connections open to the database provides adequate concurrency guarantees, trading off the expense of opening a new connection with the benefit of allowing multi-threaded write transactions.

    0 讨论(0)
  • 2020-11-28 03:11

    Check out this link. The easiest way is to do the locking yourself, and to avoid sharing the connection between threads. Another good resource can be found here, and it concludes with:

    1. Make sure you're compiling SQLite with -DTHREADSAFE=1.

    2. Make sure that each thread opens the database file and keeps its own sqlite structure.

    3. Make sure you handle the likely possibility that one or more threads collide when they access the db file at the same time: handle SQLITE_BUSY appropriately.

    4. Make sure you enclose within transactions the commands that modify the database file, like INSERT, UPDATE, DELETE, and others.

    0 讨论(0)
  • 2020-11-28 03:14

    If you use connection pooling, like in Java EE, web application, set the connection pool max. size to 1. Access will be serialized.

    0 讨论(0)
  • 2020-11-28 03:18

    Some steps when starting out with SQLlite for multithreaded use:

    1. Make sure sqlite is compiled with the multi threaded flag.
    2. You must call open on your sqlite file to create a connection on each thread, don't share connections between threads.
    3. SQLite has a very conservative threading model, when you do a write operation, which includes opening transactions that are about to do an INSERT/UPDATE/DELETE, other threads will be blocked until this operation completes.
    4. If you don't use a transaction, then transactions are implicit, so if you start a INSERT/DELETE/UPDATE, sqlite will try to acquire an exclusive lock, and complete the operation before releasing it.
    5. If you do a BEGIN EXCLUSIVE statement, it will acquire an exclusive lock before doing operations in that transaction. A COMMIT or ROLLBACK will release the lock.
    6. Your sqlite3_step, sqlite3_prepare and some other calls may return SQLITE_BUSY or SQLITE_LOCKED. SQLITE_BUSY usually means that sqlite needs to acquire the lock. The biggest difference between the two return values:
      • SQLITE_LOCKED: if you get this from a sqlite3_step statement, you MUST call sqlite3_reset on the statement handle. You should only get this on the first call to sqlite3_step, so once reset is called you can actually "retry" your sqlite3_step call. On other operations, it's the same as SQLITE_BUSY
      • SQLITE_BUSY : There is no need to call sqlite3_reset, just retry your operation after waiting a bit for the lock to be released.
    0 讨论(0)
提交回复
热议问题