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>Isolation</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="lockingsubsystem.html" title="The Locking Subsystem" />
12    <link rel="next" href="txn_ccursor.html" title="Transactional Cursors and Concurrent Applications" />
13  </head>
14  <body>
15    <div class="navheader">
16      <table width="100%" summary="Navigation header">
17        <tr>
18          <th colspan="3" align="center">Isolation</th>
19        </tr>
20        <tr>
21          <td width="20%" align="left"><a accesskey="p" href="lockingsubsystem.html">Prev</a>��</td>
22          <th width="60%" align="center">Chapter��4.��Concurrency</th>
23          <td width="20%" align="right">��<a accesskey="n" href="txn_ccursor.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="isolation"></a>Isolation</h2>
33          </div>
34        </div>
35      </div>
36      <div class="toc">
37        <dl>
38          <dt>
39            <span class="sect2">
40              <a href="isolation.html#degreesofisolation">Supported Degrees of Isolation</a>
41            </span>
42          </dt>
43          <dt>
44            <span class="sect2">
45              <a href="isolation.html#dirtyreads">Reading Uncommitted Data</a>
46            </span>
47          </dt>
48          <dt>
49            <span class="sect2">
50              <a href="isolation.html#readcommitted">Committed Reads</a>
51            </span>
52          </dt>
53          <dt>
54            <span class="sect2">
55              <a href="isolation.html#snapshot_isolation">Using Snapshot Isolation</a>
56            </span>
57          </dt>
58        </dl>
59      </div>
60      <p>
61            Isolation guarantees are an important aspect of transactional
62            protection.  Transactions
63            ensure the data your transaction is working with will not be changed by some other transaction.
64            Moreover, the modifications made by a transaction will never be viewable outside of that transaction until
65            the changes have been committed.
66        </p>
67      <p>
68            That said, there are different degrees of isolation, and you can choose to relax your isolation
69            guarantees to one degree or another depending on your application's requirements. The primary reason why
70            you might want to do this is because of performance; the more isolation you ask your transactions to
71            provide, the more locking that your application must do. With more locking comes a greater chance of
72            blocking, which in turn causes your threads to pause while waiting for a lock. Therefore, by relaxing
73            your isolation guarantees, you can <span class="emphasis"><em>potentially</em></span> improve your application's throughput.
74            Whether you actually see any improvement depends, of course, on
75            the nature of your application's data and transactions.
76        </p>
77      <div class="sect2" lang="en" xml:lang="en">
78        <div class="titlepage">
79          <div>
80            <div>
81              <h3 class="title"><a id="degreesofisolation"></a>Supported Degrees of Isolation</h3>
82            </div>
83          </div>
84        </div>
85        <p>
86                DB supports the following levels of isolation:
87            </p>
88        <div class="informaltable">
89          <table border="1" width="80%">
90            <colgroup>
91              <col />
92              <col />
93              <col />
94            </colgroup>
95            <thead>
96              <tr>
97                <th>Degree</th>
98                <th>ANSI Term</th>
99                <th>Definition</th>
100              </tr>
101            </thead>
102            <tbody>
103              <tr>
104                <td>1</td>
105                <td>READ UNCOMMITTED</td>
106                <td>
107                    Uncommitted reads means that one transaction will never
108                    overwrite another transaction's dirty data.  Dirty data is
109                    data that a transaction has modified but not yet committed
110                    to the underlying data store. However, uncommitted reads allows a 
111                    transaction to see data dirtied by another
112                    transaction. In addition, a transaction may read data
113                    dirtied by another transaction, but which subsequently
114                    is aborted by that other transaction. In this latter
115                    case, the reading transaction may be reading data that
116                    never really existed in the database.
117                </td>
118              </tr>
119              <tr>
120                <td>2</td>
121                <td>READ COMMITTED</td>
122                <td>
123                    <p>
124                    Committed read isolation means that degree 1 is observed, except that dirty data is never read. 
125                    </p>
126                    <p>
127                    In addition, this isolation level guarantees that data will never change so long as
128                    it is addressed by the cursor, but the data may change before the reading cursor is closed.
129                    In the case of a transaction, data at the current
130                    cursor position will not change, but once the cursor
131                    moves, the previous referenced data can change. This
132                    means that readers release read locks before the cursor
133                    is closed, and therefore, before the transaction
134                    completes. Note that this level of isolation causes the
135                    cursor to operate in exactly the same way as it does in
136                    the absence of a transaction.
137                    </p>
138                </td>
139              </tr>
140              <tr>
141                <td>3</td>
142                <td>SERIALIZABLE</td>
143                <td>
144                    <p>
145                    Committed read is observed, plus the data read by a transaction, T,  
146                    will never be dirtied by another transaction before T completes.
147                    This means that both read and write locks are not
148                    released until the transaction completes.
149                    </p>
150                    <p>
151                        <span>
152                        In addition, 
153                        </span>
154
155                        
156                        
157                        no transactions will see phantoms.  Phantoms are records 
158                        returned as a result of a search, but which were not seen by 
159                        the same transaction when the identical
160                        search criteria was previously used.
161                    </p>
162                    <p>
163                        This is DB's default isolation guarantee.
164                    </p>
165                </td>
166              </tr>
167            </tbody>
168          </table>
169        </div>
170        <p>
171
172    By default, DB transactions and transactional cursors offer 
173    <span>
174        serializable isolation. 
175    </span>
176    
177    
178    You can optionally reduce your isolation level by configuring DB to use
179    uncommitted read isolation. See 
180        <a class="xref" href="isolation.html#dirtyreads" title="Reading Uncommitted Data">Reading Uncommitted Data</a> 
181     for more information.
182
183        You can also configure DB to use committed read isolation. See
184            <a class="xref" href="isolation.html#readcommitted" title="Committed Reads">Committed Reads</a>
185        for more information.
186        
187  </p>
188        <p>
189          Finally, in addition to DB's normal degrees of isolation, you
190          can also use <span class="emphasis"><em>snapshot isolation</em></span>. This allows
191          you to avoid the read locks that serializable isolation requires. See
192          <a class="xref" href="isolation.html#snapshot_isolation" title="Using Snapshot Isolation">Using Snapshot Isolation</a>
193          for details.
194  </p>
195      </div>
196      <div class="sect2" lang="en" xml:lang="en">
197        <div class="titlepage">
198          <div>
199            <div>
200              <h3 class="title"><a id="dirtyreads"></a>Reading Uncommitted Data</h3>
201            </div>
202          </div>
203        </div>
204        <p>
205                Berkeley DB allows you to configure your application to read data that has been modified but not yet
206                committed by another transaction; that is, dirty data.  When you do this, you 
207                may see a performance benefit by allowing your
208                application to not have to block waiting for write locks. On the other hand, the data that your
209                application is reading may change before the transaction has completed.
210            </p>
211        <p>
212                When used with transactions, uncommitted reads means that one transaction can see data
213                modified but not yet committed by another transaction. When
214                used with transactional cursors, uncommitted reads means
215                that any database reader can see data modified by the
216                cursor before the cursor's transaction has committed.
217            </p>
218        <p>
219                Because of this, uncommitted reads allow a transaction to read data
220                that may subsequently be aborted by another transaction. In
221                this case, the reading transaction will have read data that
222                never really existed in the database.
223            </p>
224        <p>
225                To configure your application to read uncommitted data:
226            </p>
227        <div class="orderedlist">
228          <ol type="1">
229            <li>
230              <p>
231                        Open your database such that it will allow uncommitted reads. You do this by
232                            <span>
233                                specifying <code class="literal">DB_READ_UNCOMMITTED</code> when you open your database.
234                            </span>
235                            
236                    </p>
237            </li>
238            <li>
239              <p>
240                            <span>
241                                Specify <code class="literal">DB_READ_UNCOMMITTED</code>
242                                when you create the transaction, 
243                                open the cursor, or read a record from the database.
244                            </span>
245                            
246
247                    </p>
248            </li>
249          </ol>
250        </div>
251        <p>
252                For example, the following opens the database such that it supports uncommitted reads, and then creates a
253                transaction that causes all reads performed within it to use uncommitted reads. Remember that simply opening
254                the database to support uncommitted reads is not enough; you must also declare your read operations to be
255                performed using uncommitted reads. 
256            </p>
257        <pre class="programlisting">#include &lt;stdio.h&gt;
258#include &lt;stdlib.h&gt;
259
260#include "db.h"
261
262int
263main(void)
264{
265    int ret, ret_c;
266    u_int32_t db_flags, env_flags;
267    DB *dbp;
268    DB_ENV *envp;
269    DB_TXN *txn;
270    const char *db_home_dir = "/tmp/myEnvironment";
271    const char *file_name = "mydb.db";
272    const char *keystr ="thekey";
273    const char *datastr = "thedata";
274    
275    dbp = NULL;
276    envp = NULL;
277
278    /* Open the environment */
279    ret = db_env_create(&amp;envp, 0);
280    if (ret != 0) {
281        fprintf(stderr, "Error creating environment handle: %s\n",
282            db_strerror(ret));
283        return (EXIT_FAILURE);
284    }
285                                                                                                                                  
286    env_flags = DB_CREATE     |  /* If the environment does not
287                                  * exist, create it. */
288                DB_INIT_LOCK  |  /* Initialize locking */
289                DB_INIT_LOG   |  /* Initialize logging */
290                DB_INIT_MPOOL |  /* Initialize the cache */
291                DB_THREAD     |  /* Free-thread the env handle. */
292                DB_INIT_TXN;     /* Initialize transactions */
293
294    ret = envp-&gt;open(envp, db_home_dir, env_flags, 0);
295    if (ret != 0) {
296        fprintf(stderr, "Error opening environment: %s\n",
297            db_strerror(ret));
298        goto err;
299    }
300
301    /* Initialize the DB handle */
302    ret = db_create(&amp;dbp, envp, 0);
303    if (ret != 0) {
304        envp-&gt;err(envp, ret, "Database creation failed");
305        goto err;
306    }
307
308    db_flags = DB_CREATE |             /* Create the db if it does not 
309                                        * exist */
310               DB_AUTO_COMMIT |        /* Enable auto commit */
311               DB_READ_UNCOMMITTED;    /* Enable uncommitted reads */
312
313    ret = dbp-&gt;open(dbp,        /* Pointer to the database */
314                    NULL,       /* Txn pointer */
315                    file_name,  /* File name */
316                    NULL,       /* Logical db name */
317                    DB_BTREE,   /* Database type (using btree) */
318                    db_flags,   /* Open flags */
319                    0);         /* File mode. Using defaults */
320    if (ret != 0) {
321        envp-&gt;err(envp, ret, "Database '%s' open failed",
322            file_name);
323        goto err;
324    }
325
326    /* Get the txn handle */
327    txn = NULL;
328    ret = envp-&gt;txn_begin(envp, NULL, &amp;txn, DB_READ_UNCOMMITTED);
329    if (ret != 0) {
330        envp-&gt;err(envp, ret, "Transaction begin failed.");
331        goto err;
332    }
333
334    /*
335     * From here, you perform your database reads and writes as normal,
336     * committing and aborting the transactions as is necessary, and 
337     * testing for deadlock exceptions as normal (omitted for brevity). 
338     */
339
340     ...  </pre>
341      </div>
342      <div class="sect2" lang="en" xml:lang="en">
343        <div class="titlepage">
344          <div>
345            <div>
346              <h3 class="title"><a id="readcommitted"></a>Committed Reads</h3>
347            </div>
348          </div>
349        </div>
350        <p>
351                You can configure your transaction so that the data being
352                read by a transactional cursor is consistent so long as it
353                is being addressed by the cursor. However, once the cursor is done reading the 
354                    
355                    <span>
356                        record (that is, reading records from the page that it currently has locked),
357                    </span>
358                    
359                the cursor releases its lock on that
360                    
361                    <span>
362                        record or page.
363                    </span>
364                    
365                 This means that the data the cursor has read and released
366                 may change before the cursor's transaction has completed.
367              </p>
368        <p>
369                For example,
370                suppose you have two transactions, <code class="literal">Ta</code> and <code class="literal">Tb</code>. Suppose further that
371                <code class="literal">Ta</code> has a cursor that reads <code class="literal">record R</code>, but does not modify it. Normally,
372                <code class="literal">Tb</code> would then be unable to write <code class="literal">record R</code> because
373                <code class="literal">Ta</code> would be holding a read lock on it. But when you configure your transaction for
374                committed reads, <code class="literal">Tb</code> <span class="emphasis"><em>can</em></span> modify <code class="literal">record
375                R</code> before <code class="literal">Ta</code> completes, so long as the reading cursor is no longer
376                addressing the 
377                    
378                    <span>
379                        record or page.
380                    </span>
381                    
382             </p>
383        <p>
384                When you configure your application for this level of isolation, you may see better performance
385                throughput because there are fewer read locks being held by your transactions. 
386                Read committed isolation is most useful when you have a cursor that is reading and/or writing records in
387                a single direction, and that does not ever have to go back to re-read those same records. In this case,
388                you can allow DB to release read locks as it goes, rather than hold them for the life of the
389                transaction.
390             </p>
391        <p>
392                To configure your application to use committed reads, do one of the following:
393            </p>
394        <div class="itemizedlist">
395          <ul type="disc">
396            <li>
397              <p>
398                        Create your transaction such that it allows committed reads. You do this by
399                            <span>
400                                specifying <code class="literal">DB_READ_COMMITTED</code> when you open the transaction.
401                            </span>
402                            
403                    </p>
404            </li>
405            <li>
406              <p>
407                            <span>
408                                Specify <code class="literal">DB_READ_COMMITTED</code>
409                                when you open the cursor. 
410                            </span>
411                            
412                    </p>
413            </li>
414          </ul>
415        </div>
416        <p>
417                For example, the following creates a transaction that allows committed reads:
418            </p>
419        <pre class="programlisting">#include &lt;stdio.h&gt;
420#include &lt;stdlib.h&gt;
421
422#include "db.h"
423
424int
425main(void)
426{
427    int ret, ret_c;
428    u_int32_t db_flags, env_flags;
429    DB *dbp;
430    DB_ENV *envp;
431    DB_TXN *txn;
432    const char *db_home_dir = "/tmp/myEnvironment";
433    const char *file_name = "mydb.db";
434    
435    dbp = NULL;
436    envp = NULL;
437
438    /* Open the environment */
439    ret = db_env_create(&amp;envp, 0);
440    if (ret != 0) {
441        fprintf(stderr, "Error creating environment handle: %s\n",
442            db_strerror(ret));
443        return (EXIT_FAILURE);
444    }
445                                                                                                                                  
446    env_flags = DB_CREATE     |  /* If the environment does not
447                                  * exist, create it. */
448                DB_INIT_LOCK  |  /* Initialize locking */
449                DB_INIT_LOG   |  /* Initialize logging */
450                DB_INIT_MPOOL |  /* Initialize the cache */
451                DB_THREAD     |  /* Free-thread the env handle. */
452                DB_INIT_TXN;     /* Initialize transactions */
453
454    ret = envp-&gt;open(envp, db_home_dir, env_flags, 0);
455    if (ret != 0) {
456        fprintf(stderr, "Error opening environment: %s\n",
457            db_strerror(ret));
458        goto err;
459    }
460
461    /* Initialize the DB handle */
462    ret = db_create(&amp;dbp, envp, 0);
463    if (ret != 0) {
464        envp-&gt;err(envp, ret, "Database creation failed");
465        goto err;
466    }
467
468    /*
469     * Notice that we do not have to specify any flags to the database to
470     * allow committed reads (this is as opposed to uncommitted reads
471     * where we DO have to specify a flag on the database open.
472     */
473    db_flags = DB_CREATE | DB_AUTO_COMMIT;
474    ret = dbp-&gt;open(dbp,        /* Pointer to the database */
475                    NULL,       /* Txn pointer */
476                    file_name,  /* File name */
477                    NULL,       /* Logical db name */
478                    DB_BTREE,   /* Database type (using btree) */
479                    db_flags,   /* Open flags */
480                    0);         /* File mode. Using defaults */
481    if (ret != 0) {
482        envp-&gt;err(envp, ret, "Database '%s' open failed",
483            file_name);
484        goto err;
485    }
486
487    /* Get the txn handle */
488    txn = NULL;
489    /*
490     * Open the transaction and enable committed reads. All cursors open
491     * with this transaction handle will use read committed isolation.
492     */
493    ret = envp-&gt;txn_begin(envp, NULL, &amp;txn, DB_READ_COMMITTED);
494    if (ret != 0) {
495        envp-&gt;err(envp, ret, "Transaction begin failed.");
496        goto err;
497    }
498
499    /*
500     * From here, you perform your database reads and writes as normal,
501     * committing and aborting the transactions as is necessary, and 
502     * testing for deadlock exceptions as normal (omitted for brevity). 
503     *
504     * Using transactional cursors with concurrent applications is 
505     * described in more detail in the following section.
506     */
507
508     ...  </pre>
509      </div>
510      <div class="sect2" lang="en" xml:lang="en">
511        <div class="titlepage">
512          <div>
513            <div>
514              <h3 class="title"><a id="snapshot_isolation"></a>Using Snapshot Isolation</h3>
515            </div>
516          </div>
517        </div>
518        <p>
519                    By default DB uses serializable isolation. An
520                    important side effect of this isolation level is that
521                    read operations obtain read locks on database pages,
522                    and then hold those locks until the read operation is
523                    completed. 
524                    
525                    <span>
526                    When you are using transactional cursors, this 
527                    means that read locks are held until the transaction commits or
528                    aborts. In that case, over time a transactional cursor
529                    can gradually block all other transactions from writing
530                    to the database.
531                    </span>
532            </p>
533        <p>
534                    You can avoid this by using snapshot isolation.
535                    Snapshot isolation uses <span class="emphasis"><em>multiversion
536                    concurrency control</em></span> to guarantee
537                    repeatable reads. What this means is that every time a
538                    writer would take a read lock on a page, instead a copy of
539                    the page is made and the writer operates on that page
540                    copy. This frees other writers from blocking due to a
541                    read lock held on the page.
542            </p>
543        <div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
544          <h3 class="title">Note</h3>
545          <p>
546                        Snapshot isolation is strongly recommended for read-only threads when writer
547                        threads are also running, as this will eliminate read-write contention and
548                        greatly improve transaction throughput for your writer threads. However, in
549                        order for snapshot isolation to work for your reader-only threads, you must
550                        of course use transactions for your DB reads.
551                    </p>
552        </div>
553        <div class="sect3" lang="en" xml:lang="en">
554          <div class="titlepage">
555            <div>
556              <div>
557                <h4 class="title"><a id="sisolation_cost"></a>Snapshot Isolation Cost</h4>
558              </div>
559            </div>
560          </div>
561          <p>
562                    Snapshot isolation does not come without a cost.
563                    Because pages are being duplicated before being
564                    operated upon, the cache will fill up faster. This
565                    means that you might need a larger cache in order to
566                    hold the entire working set in memory.
567            </p>
568          <p>
569                    If the cache becomes full of page copies before old
570                    copies can be discarded, additional I/O will occur as
571                    pages are written to temporary "freezer" files on disk.
572                    This can substantially reduce throughput, and should be
573                    avoided if possible by configuring a large cache and
574                    keeping snapshot isolation transactions short.
575            </p>
576          <p>
577                    You can estimate how large your cache should be by
578                    taking a checkpoint, followed by a call to the 
579                    <code class="methodname">DB_ENV-&gt;log_archive()</code>
580                    
581                    
582                    method. The amount of cache required is approximately
583                    double the size of the remaining log files (that is,
584                    the log files that cannot be archived).
585            </p>
586        </div>
587        <div class="sect3" lang="en" xml:lang="en">
588          <div class="titlepage">
589            <div>
590              <div>
591                <h4 class="title"><a id="sisolation_maxtxn"></a>Snapshot Isolation Transactional Requirements</h4>
592              </div>
593            </div>
594          </div>
595          <p>
596                    In addition to an increased cache size, you may also
597                    need to increase the maximum number of transactions
598                    that your application supports. (See 
599                    <a class="xref" href="maxtxns.html" title="Configuring the Transaction Subsystem">Configuring the Transaction Subsystem</a>
600                    for details on how to set this.) 
601                    In the worst case scenario, you might need to configure your application for one
602                    more transaction for every page in the cache. This is
603                    because transactions are retained until the last page
604                    they created is evicted from the cache.
605            </p>
606        </div>
607        <div class="sect3" lang="en" xml:lang="en">
608          <div class="titlepage">
609            <div>
610              <div>
611                <h4 class="title"><a id="sisolation_whenuse"></a>When to Use Snapshot Isolation</h4>
612              </div>
613            </div>
614          </div>
615          <p>
616                           Snapshot isolation is best used when all or most
617                           of the following conditions are true:
618                   </p>
619          <div class="itemizedlist">
620            <ul type="disc">
621              <li>
622                <p>
623                                        You can have a large cache relative to your working data set size. 
624                                   </p>
625              </li>
626              <li>
627                <p>
628                                        You require repeatable reads. 
629                                   </p>
630              </li>
631              <li>
632                <p>
633                                        You will be using transactions that routinely work on
634                                        the entire database, or more commonly,
635                                        there is data in your database that will be very
636                                        frequently written by more than one transaction.
637                                   </p>
638              </li>
639              <li>
640                <p>
641                                           Read/write contention is
642                                           limiting your application's
643                                           throughput, or the application
644                                           is all or mostly read-only and
645                                           contention for the lock manager
646                                           mutex is limiting throughput.
647                                   </p>
648              </li>
649            </ul>
650          </div>
651        </div>
652        <div class="sect3" lang="en" xml:lang="en">
653          <div class="titlepage">
654            <div>
655              <div>
656                <h4 class="title"><a id="sisolation_howuse"></a>How to use Snapshot Isolation</h4>
657              </div>
658            </div>
659          </div>
660          <p>
661                           You use snapshot isolation by:
662                   </p>
663          <div class="itemizedlist">
664            <ul type="disc">
665              <li>
666                <p>
667                                           Opening the database  with
668                                           multiversion support. You can
669                                           configure this either when you
670                                           open your environment or when
671                                           you open your 
672                                           
673                                           <span>
674                                           database.
675                                           </span>
676                                           
677
678                                           <span>
679                                            Use the
680                                           <code class="literal">DB_MULTIVERSION</code>
681                                           flag to configure this support.
682                                            </span>
683
684                                           <span>
685                                            Use the
686                                            <code class="methodname">XmlContainerConfig::setMultiversion()</code>
687                                            option to configure this support when you open your
688                                            container. To configure multiversion support when you
689                                            open your environment, use the
690                                            <code class="literal">DB_MULTIVERSION</code> flag on the
691                                            environment open.
692                                           </span>
693
694                                            
695                                   </p>
696              </li>
697              <li>
698                <p>
699                                           Configure your <span>cursor or</span>
700                                           transaction to use snapshot isolation.
701                                   </p>
702                <p>
703                                           To do this, 
704                                           
705                                           <span>
706                                                pass the <code class="literal">DB_TXN_SNAPSHOT</code> flag 
707                                                when you 
708
709                                                <span>
710                                                  open the cursor or
711                                                </span>
712
713                                                create the transaction. 
714                                            
715                                                <span>
716                                                    If configured for the transaction,
717                                                     then this flag is not required
718                                                     when the cursor is opened.
719                                                </span>
720
721                                            </span>
722
723                                            
724                                   </p>
725              </li>
726            </ul>
727          </div>
728          <p>
729                           The simplest way to take advantage of snapshot
730                           isolation is for queries: keep update
731                           transactions using full read/write locking and
732                           use snapshot isolation on read-only transactions or
733                           cursors. This should minimize blocking of
734                           snapshot isolation transactions and will avoid
735                           deadlock errors.
736                   </p>
737          <p>
738                           If the application has update transactions which
739                           read many items and only update a small set (for
740                           example, scanning until a desired record is
741                           found, then modifying it), throughput may be
742                           improved by running some updates at snapshot
743                           isolation as well.  But doing this means that
744                           you must manage deadlock errors.
745                           See 
746                           <a class="xref" href="lockingsubsystem.html#deadlockresolve" title="Resolving Deadlocks">Resolving Deadlocks</a>
747                           for details.
748                   </p>
749          <p>
750                           The following code fragment turns
751                           on snapshot isolation for a transaction:
752                   </p>
753          <pre class="programlisting">#include &lt;stdio.h&gt;
754#include &lt;stdlib.h&gt;
755
756#include "db.h"
757
758int
759main(void)
760{
761    int ret, ret_c;
762    u_int32_t db_flags, env_flags;
763    DB *dbp;
764    DB_ENV *envp;
765    const char *db_home_dir = "/tmp/myEnvironment";
766    const char *file_name = "mydb.db";
767    
768    dbp = NULL;
769    envp = NULL;
770
771    /* Open the environment */
772    ret = db_env_create(&amp;envp, 0);
773    if (ret != 0) {
774        fprintf(stderr, "Error creating environment handle: %s\n",
775            db_strerror(ret));
776        return (EXIT_FAILURE);
777    }
778                                                                                                                                  
779    env_flags = DB_CREATE |    /* Create the environment if it does 
780                                * not already exist. */
781                DB_INIT_TXN  | /* Initialize transactions */
782                DB_INIT_LOCK | /* Initialize locking. */
783                DB_INIT_LOG  | /* Initialize logging */
784                DB_INIT_MPOOL| /* Initialize the in-memory cache. */
785                <strong class="userinput"><code>DB_MULTIVERSION; /* Support snapshot isolation */</code></strong>
786
787    ret = envp-&gt;open(envp, db_home_dir, env_flags, 0);
788    if (ret != 0) {
789        fprintf(stderr, "Error opening environment: %s\n",
790            db_strerror(ret));
791        goto err;
792    }
793
794    /* Initialize the DB handle */
795    ret = db_create(&amp;dbp, envp, 0);
796    if (ret != 0) {
797        envp-&gt;err(envp, ret, "Database creation failed");
798        goto err;
799    }
800
801    /* 
802     * Nothing needs to be supplied here to support snapshot isolation. 
803     * The environment does, so its databases will too.
804     */
805    db_flags = DB_CREATE | DB_AUTO_COMMIT;
806    ret = dbp-&gt;open(dbp,        /* Pointer to the database */
807                    NULL,       /* Txn pointer */
808                    file_name,  /* File name */
809                    NULL,       /* Logical db name */
810                    DB_BTREE,   /* Database type (using btree) */
811                    db_flags,   /* Open flags */
812                    0);         /* File mode. Using defaults */
813    if (ret != 0) {
814        envp-&gt;err(envp, ret, "Database '%s' open failed",
815            file_name);
816        goto err;
817    }
818
819
820    ....
821
822    ret = envp-&gt;txn_begin(envp, NULL, &amp;txn, <strong class="userinput"><code>DB_TXN_SNAPSHOT</code></strong>);
823
824    /* remainder of the program omitted for brevity */
825
826 </pre>
827        </div>
828      </div>
829    </div>
830    <div class="navfooter">
831      <hr />
832      <table width="100%" summary="Navigation footer">
833        <tr>
834          <td width="40%" align="left"><a accesskey="p" href="lockingsubsystem.html">Prev</a>��</td>
835          <td width="20%" align="center">
836            <a accesskey="u" href="txnconcurrency.html">Up</a>
837          </td>
838          <td width="40%" align="right">��<a accesskey="n" href="txn_ccursor.html">Next</a></td>
839        </tr>
840        <tr>
841          <td width="40%" align="left" valign="top">The Locking Subsystem��</td>
842          <td width="20%" align="center">
843            <a accesskey="h" href="index.html">Home</a>
844          </td>
845          <td width="40%" align="right" valign="top">��Transactional Cursors and Concurrent Applications</td>
846        </tr>
847      </table>
848    </div>
849  </body>
850</html>
851