mozilla

Compare Revisions

Storage

Change Revisions

Revision 59080:

Revision 59080 by VladVukicevic on

Revision 59081:

Revision 59081 by Mowens on

Title:
Storage
Storage
Slug:
Storage
Storage
Tags:
NeedsTechnicalReview, Interfaces, Storage, "Toolkit API", Fixit
NeedsTechnicalReview, Interfaces, Storage, "Toolkit API", Fixit
Content:

Revision 59080
Revision 59081
tt34    <p>
35      <b>Background</b>
36    </p>
37    <p>
38      While a given SQLite connection is capable of having multip
 >le statements open, its locking model limits what these statement
 >s can do concurrently (reading or writing). It is in fact possibl
 >e for multiple statements to be actively reading at one time. It 
 >is not possible, however, for multiple statements to be reading a
 >nd writing at one time <i>on the same table</i> -- even if they a
 >re derived from the same connection.
39    </p>
40    <p>
41      SQLite has a two-tiered locking model: connection level and
 > table level. Most people are familiar with the connection (datab
 >ase) level locking: multiple readers but only one writer. The tab
 >le-level (B-Tree) locks are what can sometimes be confusing. (Int
 >ernally, each table in the database has its own B-Tree, so "table
 >" and "B-Tree" are technically synonymous).
42    </p>
43    <p>
44      You would think that if you have only one connection, and i
 >t locks the database for writing, you could use multiple statemen
 >ts to do whatever you want. Not entirely. You must be aware of ta
 >ble-level (B-Tree) locks, which are maintined by statement handle
 >s traversing the database (i.e. open SELECT statements).
45    </p>
46    <p>
47      The general rule is this: a statement handle may <b>not</b>
 > modify a table (B-Tree) which other statement handles are readin
 >g (have open cursors on) -- even if that statement handle shares 
 >the same connection (transaction context, database lock, etc.) wi
 >th the other statement handles. <i>Attempts to do so will still b
 >lock (or return SQLITE_BUSY)</i>.
48    </p>
49    <p>
50      This problem often crops up when you attempt to iterate ove
 >r a table with one statement and modify records within it using a
 >nother statement. This will not work (or carries a high probabili
 >ty of not working, depending on the optimizer's involvement (see 
 >below)). The modifying statement will block because the reading s
 >tatement has an open cursor on the table.
51    </p>
52    <p>
53      The solution is to follow (1) as described above. Theoretic
 >ally, (2) actually shouldn't work with SQLite 3.x. In this scenar
 >io, database locks come into play (with multiple connections) in 
 >addition to table locks. Connection 2 (modifying connection) will
 > not be able to modify (write to) the database while the Connecti
 >on 1 (reading connection) is reading it. Connection 2 will requir
 >e an exclusive lock to execute a modifying SQL command, which it 
 >cannot get as long as Connection 1 has active statements reading 
 >the database (Connection 1 has a shared read lock during this tim
 >e which prohibits any other connections from getting an exclusive
 > lock).
54    </p>
55    <p>
56      Another option is to use a temporary table. Create a tempor
 >ary table containing the results of the table of interest, iterat
 >e over it (putting the reading statement's table lock on the temp
 > table) and then the modifing statement can make changes to the r
 >eal table without any problem. This can be done with statements d
 >erived from a single connection (transaction context). This scena
 >rio sometimes happens behind the scenes anyway as ORDER BY can pr
 >oduce temporary tables internally. However, it is not safe to ass
 >ume that the optimizer will do this in all cases. Explicitly crea
 >ting a temporary table is only safe way to do perform this latter
 > option.
57    </p>

Back to History