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