xref: /netbsd-src/external/public-domain/sqlite/man/sqlite3_busy_handler.3 (revision 82d56013d7b633d116a93943de88e08335357a7c)
1.Dd December 19, 2018
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
15The sqlite3_busy_handler(D,X,P) routine sets a callback function X
16that might be invoked with argument P whenever an attempt is made to
17access a database table associated with database connection
18D when another thread or process has the table locked.
19The sqlite3_busy_handler() interface is used to implement sqlite3_busy_timeout()
20and PRAGMA busy_timeout.
21.Pp
22If the busy callback is NULL, then SQLITE_BUSY is returned
23immediately upon encountering the lock.
24If the busy callback is not NULL, then the callback might be invoked
25with two arguments.
26.Pp
27The first argument to the busy handler is a copy of the void* pointer
28which is the third argument to sqlite3_busy_handler().
29The second argument to the busy handler callback is the number of times
30that the busy handler has been invoked previously for the same locking
31event.
32If the busy callback returns 0, then no additional attempts are made
33to access the database and SQLITE_BUSY is returned to the
34application.
35If the callback returns non-zero, then another attempt is made to access
36the database and the cycle repeats.
37.Pp
38The presence of a busy handler does not guarantee that it will be invoked
39when there is lock contention.
40If SQLite determines that invoking the busy handler could result in
41a deadlock, it will go ahead and return SQLITE_BUSY to the
42application instead of invoking the busy handler.
43Consider a scenario where one process is holding a read lock that it
44is trying to promote to a reserved lock and a second process is holding
45a reserved lock that it is trying to promote to an exclusive lock.
46The first process cannot proceed because it is blocked by the second
47and the second process cannot proceed because it is blocked by the
48first.
49If both processes invoke the busy handlers, neither will make any progress.
50Therefore, SQLite returns SQLITE_BUSY for the first process,
51hoping that this will induce the first process to release its read
52lock and allow the second process to proceed.
53.Pp
54The default busy callback is NULL.
55.Pp
56There can only be a single busy handler defined for each database connection.
57Setting a new busy handler clears any previously set handler.
58Note that calling sqlite3_busy_timeout() or evaluating
59PRAGMA busy_timeout=N will change the busy handler
60and thus clear any previously set busy handler.
61.Pp
62The busy callback should not take any actions which modify the database
63connection that invoked the busy handler.
64In other words, the busy handler is not reentrant.
65Any such actions result in undefined behavior.
66.Pp
67A busy handler must not close the database connection or prepared statement
68that invoked the busy handler.
69.Sh SEE ALSO
70.Xr sqlite3 3 ,
71.Xr sqlite3_stmt 3 ,
72.Xr sqlite3_busy_timeout 3 ,
73.Xr SQLITE_OK 3
74