xref: /netbsd-src/external/public-domain/sqlite/man/sqlite3_busy_handler.3 (revision a24efa7dea9f1f56c3bdb15a927d3516792ace1c)
1.Dd $Mdocdate$
2.Dt SQLITE3_BUSY_HANDLER 3
3.Os
4.Sh NAME
5.Nm sqlite3_busy_handler
6.Nd Register A Callback To Handle SQLITE_BUSY Errors
7.Sh SYNOPSIS
8.Ft int
9.Fo sqlite3_busy_handler
10.Fa "sqlite3*"
11.Fa "int(*)(void*,int)"
12.Fa "void*"
13.Fc
14.Sh DESCRIPTION
15This routine sets a callback function that might be invoked whenever
16an attempt is made to open a database table that another thread or
17process has locked.
18.Pp
19If the busy callback is NULL, then SQLITE_BUSY or SQLITE_IOERR_BLOCKED
20is returned immediately upon encountering the lock.
21If the busy callback is not NULL, then the callback might be invoked
22with two arguments.
23.Pp
24The first argument to the busy handler is a copy of the void* pointer
25which is the third argument to sqlite3_busy_handler().
26The second argument to the busy handler callback is the number of times
27that the busy handler has been invoked for this locking event.
28If the busy callback returns 0, then no additional attempts are made
29to access the database and SQLITE_BUSY or SQLITE_IOERR_BLOCKED
30is returned.
31If the callback returns non-zero, then another attempt is made to open
32the database for reading and the cycle repeats.
33.Pp
34The presence of a busy handler does not guarantee that it will be invoked
35when there is lock contention.
36If SQLite determines that invoking the busy handler could result in
37a deadlock, it will go ahead and return SQLITE_BUSY or SQLITE_IOERR_BLOCKED
38instead of invoking the busy handler.
39Consider a scenario where one process is holding a read lock that it
40is trying to promote to a reserved lock and a second process is holding
41a reserved lock that it is trying to promote to an exclusive lock.
42The first process cannot proceed because it is blocked by the second
43and the second process cannot proceed because it is blocked by the
44first.
45If both processes invoke the busy handlers, neither will make any progress.
46Therefore, SQLite returns SQLITE_BUSY for the first process,
47hoping that this will induce the first process to release its read
48lock and allow the second process to proceed.
49.Pp
50The default busy callback is NULL.
51.Pp
52The SQLITE_BUSY error is converted to SQLITE_IOERR_BLOCKED
53when SQLite is in the middle of a large transaction where all the changes
54will not fit into the in-memory cache.
55SQLite will already hold a RESERVED lock on the database file, but
56it needs to promote this lock to EXCLUSIVE so that it can spill cache
57pages into the database file without harm to concurrent readers.
58If it is unable to promote the lock, then the in-memory cache will
59be left in an inconsistent state and so the error code is promoted
60from the relatively benign SQLITE_BUSY to the more severe
61SQLITE_IOERR_BLOCKED.
62This error code promotion forces an automatic rollback of the changes.
63See the <a href="/cvstrac/wiki?p=CorruptionFollowingBusyError"> CorruptionFollowingBusyError</a>
64wiki page for a discussion of why this is important.
65.Pp
66There can only be a single busy handler defined for each database connection.
67Setting a new busy handler clears any previously set handler.
68Note that calling sqlite3_busy_timeout() will
69also set or clear the busy handler.
70.Pp
71The busy callback should not take any actions which modify the database
72connection that invoked the busy handler.
73Any such actions result in undefined behavior.
74.Pp
75A busy handler must not close the database connection or prepared statement
76that invoked the busy handler.
77.Sh SEE ALSO
78.Xr sqlite3 3 ,
79.Xr sqlite3_stmt 3 ,
80.Xr sqlite3_busy_timeout 3 ,
81.Xr SQLITE_OK 3 ,
82.Xr SQLITE_IOERR_READ 3
83