1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml">
4  <head>
5    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6    <title>The Locking Subsystem</title>
7    <link rel="stylesheet" href="gettingStarted.css" type="text/css" />
8    <meta name="generator" content="DocBook XSL Stylesheets V1.73.2" />
9    <link rel="start" href="index.html" title="Getting Started with Berkeley DB Transaction Processing" />
10    <link rel="up" href="txnconcurrency.html" title="Chapter 4. Concurrency" />
11    <link rel="prev" href="blocking_deadlocks.html" title="Locks, Blocks, and Deadlocks" />
12    <link rel="next" href="isolation.html" title="Isolation" />
13  </head>
14  <body>
15    <div class="navheader">
16      <table width="100%" summary="Navigation header">
17        <tr>
18          <th colspan="3" align="center">The Locking Subsystem</th>
19        </tr>
20        <tr>
21          <td width="20%" align="left"><a accesskey="p" href="blocking_deadlocks.html">Prev</a> </td>
22          <th width="60%" align="center">Chapter 4. Concurrency</th>
23          <td width="20%" align="right"> <a accesskey="n" href="isolation.html">Next</a></td>
24        </tr>
25      </table>
26      <hr />
27    </div>
28    <div class="sect1" lang="en" xml:lang="en">
29      <div class="titlepage">
30        <div>
31          <div>
32            <h2 class="title" style="clear: both"><a id="lockingsubsystem"></a>The Locking Subsystem</h2>
33          </div>
34        </div>
35      </div>
36      <div class="toc">
37        <dl>
38          <dt>
39            <span class="sect2">
40              <a href="lockingsubsystem.html#configuringlock">Configuring the Locking Subsystem</a>
41            </span>
42          </dt>
43          <dt>
44            <span class="sect2">
45              <a href="lockingsubsystem.html#configdeadlkdetect">Configuring Deadlock Detection</a>
46            </span>
47          </dt>
48          <dt>
49            <span class="sect2">
50              <a href="lockingsubsystem.html#deadlockresolve">Resolving Deadlocks</a>
51            </span>
52          </dt>
53        </dl>
54      </div>
55      <p>
56            In order to allow concurrent operations, DB provides the locking
57            subsystem. This subsystem provides inter- and intra- process
58            concurrency mechanisms. It is extensively used by DB concurrent
59            applications, but it can also be generally used for non-DB
60            resources.
61        </p>
62      <p>
63            This section describes the locking subsystem as it is used to
64            protect DB resources. In particular, issues on configuration are
65            examined here. For information on using the locking subsystem to
66            manage non-DB resources, see the
67            <em class="citetitle">Berkeley DB Programmer's Reference Guide</em>.
68        </p>
69      <div class="sect2" lang="en" xml:lang="en">
70        <div class="titlepage">
71          <div>
72            <div>
73              <h3 class="title"><a id="configuringlock"></a>Configuring the Locking Subsystem</h3>
74            </div>
75          </div>
76        </div>
77        <p>
78                You initialize the locking subsystem by specifying
79                    
80                    <span>
81                        <code class="literal">true</code> to the 
82                            <code class="methodname">EnvironmentConfig.setInitializeLocking()</code>
83                        method.
84                    </span>
85            </p>
86        <p>
87                Before opening your environment, you can configure various
88                maximum values for your locking subsystem. Note that these
89                limits can only be configured before the environment is
90                opened. Also, these methods configure the entire environment,
91                not just a specific environment handle.
92            </p>
93        <p>
94                Finally, each bullet below identifies the 
95                <code class="filename">DB_CONFIG</code> file parameter that can be used
96                to specify the specific locking limit. If used, these
97                <code class="filename">DB_CONFIG</code> file parameters override any
98                value that you might specify using the environment handle. 
99            </p>
100        <p>
101                The limits that you can configure are as follows:
102            </p>
103        <div class="itemizedlist">
104          <ul type="disc">
105            <li>
106              <p>
107                        The maximum number of lockers
108                        supported by the environment. This value is used by
109                        the environment when it is opened to estimate the amount
110                        of space that it should allocate for various internal
111                        data structures. By default, 1,000 lockers are
112                        supported.
113                    </p>
114              <p>
115                        To configure this value, use the 
116                        
117                        <span>
118                            <code class="methodname">EnvironmentConfig.setMaxLockers()</code>
119                         method.
120                        </span>
121                    </p>
122              <p>
123                        As an alternative to this method, you can configure this
124                        value using the <code class="filename">DB_CONFIG</code> file's
125                        <code class="literal">set_lk_max_lockers</code> parameter.
126                    </p>
127            </li>
128            <li>
129              <p>
130                        The maximum number of locks supported by the environment.
131                        By default, 1,000 locks are supported.
132                    </p>
133              <p>
134                        To configure this value, use the 
135                        
136                        <span>
137                            <code class="methodname">EnvironmentConfig.setMaxLocks()</code>
138                         method.
139                        </span>
140                    </p>
141              <p>
142                        As an alternative to this method, you can configure this
143                        value using the <code class="filename">DB_CONFIG</code> file's
144                        <code class="literal">set_lk_max_locks</code> parameter.
145                    </p>
146            </li>
147            <li>
148              <p>
149                        The maximum number of locked objects supported by the environment.
150                        By default, 1,000 objects can be locked.
151                    </p>
152              <p>
153                        To configure this value, use the 
154                        
155                        <span>
156                            <code class="methodname">EnvironmentConfig.setMaxLockObjects()</code>
157                         method.
158                        </span>
159                    </p>
160              <p>
161                        As an alternative to this method, you can configure this
162                        value using the <code class="filename">DB_CONFIG</code> file's
163                        <code class="literal">set_lk_max_objects</code> parameter.
164                    </p>
165            </li>
166          </ul>
167        </div>
168        <p>
169                For a definition of lockers, locks, and locked objects, see
170                <a class="xref" href="blocking_deadlocks.html#lockresources" title="Lock Resources">Lock Resources</a>.
171            </p>
172        <p>
173                For example, to configure the maximum number of locks that your
174                environment can use:
175            </p>
176        <pre class="programlisting">package db.txn;
177                                                                                                                                     
178import com.sleepycat.db.DatabaseException;
179import com.sleepycat.db.Environment;
180import com.sleepycat.db.EnvironmentConfig;
181
182import java.io.File;
183import java.io.FileNotFoundException;
184                                                                                                                                     
185...
186                                                                                                                                     
187Environment myEnv = null;
188try {
189    EnvironmentConfig myEnvConfig = new EnvironmentConfig();
190    myEnvConfig.setTransactional(true);
191    myEnvConfig.setMaxLocks(5000);
192
193    myEnv = new Environment(new File("/my/env/home"),
194                              myEnvConfig);
195
196} catch (DatabaseException de) {
197    // Exception handling goes here
198} catch (FileNotFoundException fnfe) {
199     // Exception handling goes here
200}</pre>
201      </div>
202      <div class="sect2" lang="en" xml:lang="en">
203        <div class="titlepage">
204          <div>
205            <div>
206              <h3 class="title"><a id="configdeadlkdetect"></a>Configuring Deadlock Detection</h3>
207            </div>
208          </div>
209        </div>
210        <p>
211                In order for DB to know that a deadlock has occurred,
212                some mechanism must be used to perform deadlock
213                detection. There are three ways that deadlock detection can
214                occur:
215            </p>
216        <div class="orderedlist">
217          <ol type="1">
218            <li>
219              <p>
220                        Allow DB to internally detect deadlocks as they
221                        occur.
222                    </p>
223              <p>
224                        To do this, you use
225                            
226                            
227                            <span><code class="methodname">EnvironmentConfig.setLockDetectMode()</code>.</span>
228                            This method causes DB to walk its internal lock table 
229                            looking for a deadlock whenever a lock request
230                            is blocked. This method also identifies how DB decides which lock
231                            requests are rejected when deadlocks are detected. For example,
232                            DB can decide to reject the lock request for the transaction
233                            that has the most number of locks, the least number of locks,
234                            holds the oldest lock, holds the most number of write locks, and
235                            so forth (see the API reference documentation for a complete
236                            list of the lock detection policies).
237                    </p>
238              <p>
239                        You can call this method at any time during your application's
240                        lifetime, but typically it is used before you open your environment.
241                    </p>
242              <p>
243                        Note that how you want DB to decide which thread of control should break a deadlock is
244                        extremely dependent on the nature of your application. It is not unusual for some performance
245                        testing to be required in order to make this determination. That said, a transaction that is
246                        holding the maximum number of locks is usually indicative of the transaction that has performed
247                        the most amount of work. Frequently you will not want a transaction that has performed a lot of
248                        work to abandon its efforts and start all over again. It is not therefore uncommon for
249                        application developers to initially select the transaction with the <span class="emphasis"><em>minimum</em></span>
250                        number of write locks to break the deadlock.
251                    </p>
252              <p>
253                        Using this mechanism for deadlock detection means
254                        that your application will never have to wait on a
255                        lock before discovering that a deadlock has
256                        occurred. However, walking the lock table every
257                        time a lock request is blocked can be expensive
258                        from a performance perspective.
259                    </p>
260            </li>
261            <li>
262              <p>
263                        Use a dedicated thread or external process to perform
264                        deadlock detection. Note that this thread must be
265                        performing no other database operations beyond deadlock
266                        detection.
267                    </p>
268              <p>
269                        To externally perform lock detection, you can use
270                        either the
271                            
272                            
273                            <code class="methodname">Environment.detectDeadlocks()</code>
274                           method, or use the
275                           <span class="command"><strong>db_deadlock</strong></span> command line
276                           utility. This method (or command) causes DB to walk the
277                           lock table looking for deadlocks. 
278                    </p>
279              <p>
280                        Note that like
281                            
282                            
283                            <span><code class="methodname">EnvironmentConfig.setLockDetectMode()</code>,</span>
284                        you also use this method (or command line utility)
285                        to identify which lock requests are rejected in the
286                        event that a deadlock is detected.
287                    </p>
288              <p>
289                        Applications that perform deadlock detection in
290                        this way typically run deadlock detection between every few
291                        seconds and a minute. This means that your
292                        application may have to wait to be notified of a
293                        deadlock, but you also save the overhead of walking
294                        the lock table every time a lock request is blocked.
295                    </p>
296            </li>
297            <li>
298              <p>
299                        Lock timeouts.
300                    </p>
301              <p>
302                        You can configure your locking subsystem such that
303                        it times out any lock that is not released within a
304                        specified amount of time. To do this, use the
305                            
306                            
307                            <span><code class="methodname">EnvironmentConfig.setLockTimeout()</code></span>
308                        method. 
309                            Note that lock timeouts are only checked when a
310                            lock request is blocked or when deadlock
311                            detection is otherwise performed. Therefore, a lock can have timed out and still be held for
312                            some length of time until DB has a reason to examine its locking tables.
313                    </p>
314              <p>
315                        Be aware that extremely long-lived transactions, or
316                        operations that hold locks for a long time, may be
317                        inappropriately timed out before the transaction or
318                        operation has a chance to complete. You should
319                        therefore use this mechanism only if you know your
320                        application will hold locks for very short periods
321                        of time.
322                    </p>
323            </li>
324          </ol>
325        </div>
326        <p>
327                For example, to configure your application such that DB
328                checks the lock table for deadlocks every time a lock
329                request is blocked:
330            </p>
331        <pre class="programlisting">package db.txn;
332
333import com.sleepycat.db.Environment;
334import com.sleepycat.db.EnvironmentConfig;
335import com.sleepycat.db.LockDetectMode;
336
337import java.io.File;
338
339...
340
341Environment myEnv = null;
342try {
343    EnvironmentConfig myEnvConfig = new EnvironmentConfig();
344    myEnvConfig.setTransactional(true);
345    myEnvConfig.setInitializeCache(true);
346    myEnvConfig.setInitializeLocking(true);
347    myEnvConfig.setInitializeLogging(true);   
348
349    // Configure db to perform deadlock detection internally, and to
350    // choose the transaction that has performed the least amount 
351    // of writing to break the deadlock in the event that one 
352    // is detected.
353    envConfig.setLockDetectMode(LockDetectMode.MINWRITE);
354
355    myEnv = new Environment(new File("/my/env/home"),
356                              myEnvConfig);
357
358    // From here, you open your databases, proceed with your 
359    // database operations, and respond to deadlocks as 
360    // is normal (omitted for brevity).
361
362    ...</pre>
363        <p>
364        Finally, the following command line call causes
365        deadlock detection to be run against the
366        environment contained in <code class="literal">/export/dbenv</code>. The 
367        transaction with the youngest lock is chosen to break the
368        deadlock:
369    </p>
370        <pre class="programlisting">&gt; /usr/local/db_install/bin/db_deadlock -h /export/dbenv -a y</pre>
371        <p>
372        For more information, see the
373        <a class="ulink" href="http://www.oracle.com/technology/documentation/berkeley-db/db/utility/db_deadlock.html" target="_top">
374            <code class="literal">db_deadlock</code> reference documentation.
375        </a>
376    </p>
377      </div>
378      <div class="sect2" lang="en" xml:lang="en">
379        <div class="titlepage">
380          <div>
381            <div>
382              <h3 class="title"><a id="deadlockresolve"></a>Resolving Deadlocks</h3>
383            </div>
384          </div>
385        </div>
386        <p>
387                When DB determines that a deadlock has occurred, it will
388                select a thread of control to resolve the deadlock and then 
389                    
390                    
391                    <span>
392                        throws <code class="literal">DeadlockException</code> in that
393                        thread.
394                    </span>
395                    
396                 If a deadlock is detected, the thread must:
397            </p>
398        <div class="orderedlist">
399          <ol type="1">
400            <li>
401              <p>
402                        Cease all read and write operations.
403                    </p>
404            </li>
405            <li>
406              <p>
407                        Close all open cursors.
408                    </p>
409            </li>
410            <li>
411              <p>
412                        Abort the transaction.
413                    </p>
414            </li>
415            <li>
416              <p>
417                        Optionally retry the operation. If your application
418                        retries deadlocked operations, the new attempt must
419                        be made using a new transaction.
420                    </p>
421            </li>
422          </ol>
423        </div>
424        <div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
425          <h3 class="title">Note</h3>
426          <p>
427                    If a thread has deadlocked, it may not make any
428                    additional database calls using the handle that has
429                    deadlocked.
430                </p>
431        </div>
432        <p>
433                For example:
434            </p>
435        <pre class="programlisting">// retry_count is a counter used to identify how many times
436// we've retried this operation. To avoid the potential for 
437// endless looping, we won't retry more than MAX_DEADLOCK_RETRIES 
438// times.
439
440// txn is a transaction handle.
441// key and data are DatabaseEntry handles. Their usage is not shown here.
442while (retry_count &lt; MAX_DEADLOCK_RETRIES) {
443    try {
444        txn = myEnv.beginTransaction(null, null);
445        myDatabase.put(txn, key, data);
446        txn.commit();
447        return 0;
448    } catch (DeadlockException de) {
449        try {
450            // Abort the transaction and increment the
451            // retry counter
452            txn.abort();
453            retry_count++;
454            if (retry_count &gt;= MAX_DEADLOCK_RETRIES) {
455                System.err.println("Exceeded retry limit. Giving up.");
456                return -1;
457            }
458        } catch (DatabaseException ae) {
459            System.err.println("txn abort failed: " + ae.toString());
460            return -1;    
461        }
462    } catch (DatabaseException e) {
463        try {
464            // Abort the transaction.
465            txn.abort();
466        } catch (DatabaseException ae) {
467            System.err.println("txn abort failed: " + ae.toString());
468            return -1;    
469        }
470    }
471} </pre>
472      </div>
473    </div>
474    <div class="navfooter">
475      <hr />
476      <table width="100%" summary="Navigation footer">
477        <tr>
478          <td width="40%" align="left"><a accesskey="p" href="blocking_deadlocks.html">Prev</a> </td>
479          <td width="20%" align="center">
480            <a accesskey="u" href="txnconcurrency.html">Up</a>
481          </td>
482          <td width="40%" align="right"> <a accesskey="n" href="isolation.html">Next</a></td>
483        </tr>
484        <tr>
485          <td width="40%" align="left" valign="top">Locks, Blocks, and Deadlocks </td>
486          <td width="20%" align="center">
487            <a accesskey="h" href="index.html">Home</a>
488          </td>
489          <td width="40%" align="right" valign="top"> Isolation</td>
490        </tr>
491      </table>
492    </div>
493  </body>
494</html>
495