1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
3
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
4
<title>Register A Callback To Handle SQLITE_BUSY Errors</title>
5
<style type="text/css">
8
font-family: Verdana, sans-serif;
13
a:visited { color: #734559 }
15
.logo { position:absolute; margin:3px; }
31
.toolbar a { color: white; text-decoration: none; padding: 6px 12px; }
32
.toolbar a:visited { color: white; }
33
.toolbar a:hover { color: #044a64; background: white; }
35
.content { margin: 5%; }
36
.content dt { font-weight:bold; }
37
.content dd { margin-bottom: 25px; margin-left:20%; }
38
.content ul { padding:0px; padding-left: 15px; margin:0px; }
41
.se { background: url(../images/se.gif) 100% 100% no-repeat #044a64}
42
.sw { background: url(../images/sw.gif) 0% 100% no-repeat }
43
.ne { background: url(../images/ne.gif) 100% 0% no-repeat }
44
.nw { background: url(../images/nw.gif) 0% 0% no-repeat }
46
/* Things for "fancyformat" documents start here. */
47
.fancy img+p {font-style:italic}
48
.fancy .codeblock i { color: darkblue; }
49
.fancy h1,.fancy h2,.fancy h3,.fancy h4 {font-weight:normal;color:#044a64}
50
.fancy h2 { margin-left: 10px }
51
.fancy h3 { margin-left: 20px }
52
.fancy h4 { margin-left: 30px }
53
.fancy th {white-space:nowrap;text-align:left;border-bottom:solid 1px #444}
54
.fancy th, .fancy td {padding: 0.2em 1ex; vertical-align:top}
55
.fancy #toc a { color: darkblue ; text-decoration: none }
56
.fancy .todo { color: #AA3333 ; font-style : italic }
57
.fancy .todo:before { content: 'TODO:' }
58
.fancy p.todo { border: solid #AA3333 1px; padding: 1ex }
59
.fancy img { display:block; }
60
.fancy :link:hover, .fancy :visited:hover { background: wheat }
61
.fancy p,.fancy ul,.fancy ol { margin: 1em 5ex }
62
.fancy li p { margin: 1em 0 }
63
/* End of "fancyformat" specific rules. */
69
<div><!-- container div to satisfy validator -->
71
<a href="../index.html">
72
<img class="logo" src="../images/sqlite370_banner.gif" alt="SQLite Logo"
74
<div><!-- IE hack to prevent disappearing logo--></div>
75
<div class="tagline">Small. Fast. Reliable.<br>Choose any three.</div>
77
<table width=100% style="clear:both"><tr><td>
78
<div class="se"><div class="sw"><div class="ne"><div class="nw">
79
<table width=100% style="padding:0;margin:0;cell-spacing:0"><tr>
82
<a href="../about.html">About</a>
83
<a href="../sitemap.html">Sitemap</a>
84
<a href="../docs.html">Documentation</a>
85
<a href="../download.html">Download</a>
86
<a href="../copyright.html">License</a>
87
<a href="../news.html">News</a>
88
<a href="../support.html">Support</a>
91
gMsg = "Search SQLite Docs..."
92
function entersearch() {
93
var q = document.getElementById("q");
94
if( q.value == gMsg ) { q.value = "" }
95
q.style.color = "black"
96
q.style.fontStyle = "normal"
98
function leavesearch() {
99
var q = document.getElementById("q");
100
if( q.value == "" ) {
102
q.style.color = "#044a64"
103
q.style.fontStyle = "italic"
108
<div style="padding:0 1em 0px 0;white-space:nowrap">
109
<form name=f method="GET" action="http://www.sqlite.org/search">
110
<input id=q name=q type=text
111
onfocus="entersearch()" onblur="leavesearch()" style="width:24ex;padding:1px 1ex; border:solid white 1px; font-size:0.9em ; font-style:italic;color:#044a64;" value="Search SQLite Docs...">
112
<input type=submit value="Go" style="border:solid white 1px;background-color:#044a64;color:white;font-size:0.9em;padding:0 1ex">
116
</div></div></div></div>
118
<div class=startsearch></div>
120
<a href="intro.html"><h2>SQLite C Interface</h2></a><h2>Register A Callback To Handle SQLITE_BUSY Errors</h2><blockquote><pre>int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
121
</pre></blockquote><p>
122
This routine sets a callback function that might be invoked whenever
123
an attempt is made to open a database table that another thread
124
or process has locked.</p>
126
<p>If the busy callback is NULL, then <a href="../c3ref/c_abort.html">SQLITE_BUSY</a> or <a href="../c3ref/c_abort_rollback.html">SQLITE_IOERR_BLOCKED</a>
127
is returned immediately upon encountering the lock. If the busy callback
128
is not NULL, then the callback might be invoked with two arguments.</p>
130
<p>The first argument to the busy handler is a copy of the void* pointer which
131
is the third argument to sqlite3_busy_handler(). The second argument to
132
the busy handler callback is the number of times that the busy handler has
133
been invoked for this locking event. If the
134
busy callback returns 0, then no additional attempts are made to
135
access the database and <a href="../c3ref/c_abort.html">SQLITE_BUSY</a> or <a href="../c3ref/c_abort_rollback.html">SQLITE_IOERR_BLOCKED</a> is returned.
136
If the callback returns non-zero, then another attempt
137
is made to open the database for reading and the cycle repeats.</p>
139
<p>The presence of a busy handler does not guarantee that it will be invoked
140
when there is lock contention. If SQLite determines that invoking the busy
141
handler could result in a deadlock, it will go ahead and return <a href="../c3ref/c_abort.html">SQLITE_BUSY</a>
142
or <a href="../c3ref/c_abort_rollback.html">SQLITE_IOERR_BLOCKED</a> instead of invoking the busy handler.
143
Consider a scenario where one process is holding a read lock that
144
it is trying to promote to a reserved lock and
145
a second process is holding a reserved lock that it is trying
146
to promote to an exclusive lock. The first process cannot proceed
147
because it is blocked by the second and the second process cannot
148
proceed because it is blocked by the first. If both processes
149
invoke the busy handlers, neither will make any progress. Therefore,
150
SQLite returns <a href="../c3ref/c_abort.html">SQLITE_BUSY</a> for the first process, hoping that this
151
will induce the first process to release its read lock and allow
152
the second process to proceed.</p>
154
<p>The default busy callback is NULL.</p>
156
<p>The <a href="../c3ref/c_abort.html">SQLITE_BUSY</a> error is converted to <a href="../c3ref/c_abort_rollback.html">SQLITE_IOERR_BLOCKED</a>
157
when SQLite is in the middle of a large transaction where all the
158
changes will not fit into the in-memory cache. SQLite will
159
already hold a RESERVED lock on the database file, but it needs
160
to promote this lock to EXCLUSIVE so that it can spill cache
161
pages into the database file without harm to concurrent
162
readers. If it is unable to promote the lock, then the in-memory
163
cache will be left in an inconsistent state and so the error
164
code is promoted from the relatively benign <a href="../c3ref/c_abort.html">SQLITE_BUSY</a> to
165
the more severe <a href="../c3ref/c_abort_rollback.html">SQLITE_IOERR_BLOCKED</a>. This error code promotion
166
forces an automatic rollback of the changes. See the
167
<a href="/cvstrac/wiki?p=CorruptionFollowingBusyError">
168
CorruptionFollowingBusyError</a> wiki page for a discussion of why
169
this is important.</p>
171
<p>There can only be a single busy handler defined for each
172
<a href="../c3ref/sqlite3.html">database connection</a>. Setting a new busy handler clears any
173
previously set handler. Note that calling <a href="../c3ref/busy_timeout.html">sqlite3_busy_timeout()</a>
174
will also set or clear the busy handler.</p>
176
<p>The busy callback should not take any actions which modify the
177
database connection that invoked the busy handler. Any such actions
178
result in undefined behavior.</p>
180
<p>A busy handler must not close the database connection
181
or <a href="../c3ref/stmt.html">prepared statement</a> that invoked the busy handler.
182
</p><p>See also lists of
183
<a href="objlist.html">Objects</a>,
184
<a href="constlist.html">Constants</a>, and
185
<a href="funclist.html">Functions</a>.</p>