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>Chapter��3.��Transaction Basics</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="index.html" title="Getting Started with Berkeley DB Transaction Processing" />
11    <link rel="prev" href="envopen.html" title="Opening a Transactional Environment and Database" />
12    <link rel="next" href="abortresults.html" title="Aborting a Transaction" />
13  </head>
14  <body>
15    <div class="navheader">
16      <table width="100%" summary="Navigation header">
17        <tr>
18          <th colspan="3" align="center">Chapter��3.��Transaction Basics</th>
19        </tr>
20        <tr>
21          <td width="20%" align="left"><a accesskey="p" href="envopen.html">Prev</a>��</td>
22          <th width="60%" align="center">��</th>
23          <td width="20%" align="right">��<a accesskey="n" href="abortresults.html">Next</a></td>
24        </tr>
25      </table>
26      <hr />
27    </div>
28    <div class="chapter" lang="en" xml:lang="en">
29      <div class="titlepage">
30        <div>
31          <div>
32            <h2 class="title"><a id="usingtxns"></a>Chapter��3.��Transaction Basics</h2>
33          </div>
34        </div>
35      </div>
36      <div class="toc">
37        <p>
38          <b>Table of Contents</b>
39        </p>
40        <dl>
41          <dt>
42            <span class="sect1">
43              <a href="usingtxns.html#commitresults">Committing a Transaction</a>
44            </span>
45          </dt>
46          <dd>
47            <dl>
48              <dt>
49                <span class="sect2">
50                  <a href="usingtxns.html#nodurabletxn">Non-Durable Transactions</a>
51                </span>
52              </dt>
53            </dl>
54          </dd>
55          <dt>
56            <span class="sect1">
57              <a href="abortresults.html">Aborting a Transaction</a>
58            </span>
59          </dt>
60          <dt>
61            <span class="sect1">
62              <a href="autocommit.html">Auto Commit</a>
63            </span>
64          </dt>
65          <dt>
66            <span class="sect1">
67              <a href="nestedtxn.html">Nested Transactions</a>
68            </span>
69          </dt>
70          <dt>
71            <span class="sect1">
72              <a href="txncursor.html">Transactional Cursors</a>
73            </span>
74          </dt>
75          <dt>
76            <span class="sect1">
77              <a href="txnindices.html">Secondary Indices with Transaction Applications</a>
78            </span>
79          </dt>
80          <dt>
81            <span class="sect1">
82              <a href="maxtxns.html">Configuring the Transaction Subsystem</a>
83            </span>
84          </dt>
85        </dl>
86      </div>
87      <p>
88        Once you have enabled transactions for your environment and your databases,
89        you can use them to protect your database operations. You do this by
90        acquiring a transaction handle and then using that handle for any
91        database operation that you want to participate in that transaction.
92     </p>
93      <p>
94        You obtain a transaction handle using the
95        <span><code class="methodname">DB_ENV-&gt;txn_begin()</code> method.</span>
96        
97        
98        
99        
100     </p>
101      <p>
102        Once you have completed all of the operations that you want to include
103        in the transaction, you must commit the transaction using the 
104        <span><code class="methodname">DB_TXN-&gt;commit()</code> method.</span>
105        
106        
107        
108        
109        
110    </p>
111      <p>
112        If, for any reason, you want to abandon the transaction, you abort
113        it using 
114        <span><code class="methodname">DB_TXN-&gt;abort()</code>.</span>
115        
116        
117        
118        
119
120        
121    </p>
122      <p>
123        Any transaction handle that has been committed or aborted can no longer
124        be used by your application.
125    </p>
126      <p>
127        Finally, you must make sure that all transaction handles are either
128        committed or aborted before closing your databases and environment.
129    </p>
130      <div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
131        <h3 class="title">Note</h3>
132        <p>
133            If you only want to transaction protect a single database write operation, you can use auto commit to 
134            perform the transaction administration. When you use auto commit, you do not need an explicit transaction
135            handle. See <a class="xref" href="autocommit.html" title="Auto Commit">Auto Commit</a> for more information.
136        </p>
137      </div>
138      <p>
139        For example, the following example opens a transactional-enabled environment and
140        database, obtains a transaction handle, and then performs a write
141        operation under its protection. In the event of any failure in the
142        write operation, the transaction is aborted and the database is left in a
143        state as if no operations had ever been attempted in the first place.
144    </p>
145      <pre class="programlisting">#include &lt;stdio.h&gt;
146#include &lt;stdlib.h&gt;
147
148#include "db.h"
149
150int
151main(void)
152{
153    int ret, ret_c;
154    u_int32_t db_flags, env_flags;
155    DB *dbp;
156    DB_ENV *envp;
157    DBT key, data;
158    DB_TXN *txn;
159    const char *db_home_dir = "/tmp/myEnvironment";
160    const char *file_name = "mydb.db";
161    const char *keystr ="thekey";
162    const char *datastr = "thedata";
163    
164    dbp = NULL;
165    envp = NULL;
166
167    /* Open the environment */
168    ret = db_env_create(&amp;envp, 0);
169    if (ret != 0) {
170        fprintf(stderr, "Error creating environment handle: %s\n",
171            db_strerror(ret));
172        return (EXIT_FAILURE);
173    }
174                                                                                                                                  
175    env_flags = DB_CREATE |    /* Create the environment if it does 
176                                * not already exist. */
177                DB_INIT_TXN  | /* Initialize transactions */
178                DB_INIT_LOCK | /* Initialize locking. */
179                DB_INIT_LOG  | /* Initialize logging */
180                DB_INIT_MPOOL; /* Initialize the in-memory cache. */
181
182    ret = envp-&gt;open(envp, db_home_dir, env_flags, 0);
183    if (ret != 0) {
184        fprintf(stderr, "Error opening environment: %s\n",
185            db_strerror(ret));
186        goto err;
187    }
188
189    /* Initialize the DB handle */
190    ret = db_create(&amp;dbp, envp, 0);
191    if (ret != 0) {
192        envp-&gt;err(envp, ret, "Database creation failed");
193        goto err;
194    }
195
196    db_flags = DB_CREATE | DB_AUTO_COMMIT;
197    /* 
198     * Open the database. Note that we are using auto commit for the open, 
199     * so the database is able to support transactions.
200     */
201    ret = dbp-&gt;open(dbp,        /* Pointer to the database */
202                    NULL,       /* Txn pointer */
203                    file_name,  /* File name */
204                    NULL,       /* Logical db name */
205                    DB_BTREE,   /* Database type (using btree) */
206                    db_flags,   /* Open flags */
207                    0);         /* File mode. Using defaults */
208    if (ret != 0) {
209        envp-&gt;err(envp, ret, "Database '%s' open failed",
210            file_name);
211        goto err;
212    }
213
214    /* Prepare the DBTs */
215    memset(&amp;key, 0, sizeof(DBT));
216    memset(&amp;data, 0, sizeof(DBT));
217
218    key.data = &amp;keystr;
219    key.size = strlen(keystr) + 1;
220    data.data = &amp;datastr;
221    data.size = strlen(datastr) + 1;
222
223    /* Get the txn handle */
224    txn = NULL;
225    ret = envp-&gt;txn_begin(envp, NULL, &amp;txn, 0);
226    if (ret != 0) {
227        envp-&gt;err(envp, ret, "Transaction begin failed.");
228        goto err;
229    }
230
231    /*
232     * Perform the database write. If this fails, abort the transaction.
233     */
234    ret = dbp-&gt;put(dbp, txn, &amp;key, &amp;data, 0);
235    if (ret != 0) {
236        envp-&gt;err(envp, ret, "Database put failed.");
237        txn-&gt;abort(txn);
238        goto err;
239    }
240
241    /* 
242     * Commit the transaction. Note that the transaction handle
243     * can no longer be used.
244     */ 
245    ret = txn-&gt;commit(txn, 0);
246    if (ret != 0) {
247        envp-&gt;err(envp, ret, "Transaction commit failed.");
248        goto err;
249    }
250
251err:
252    /* Close the database */
253    if (dbp != NULL) {
254        ret_c = dbp-&gt;close(dbp, 0);
255        if (ret_c != 0) {
256            envp-&gt;err(envp, ret_c, "Database close failed.");
257            ret = ret_c
258        }
259    }
260
261
262    /* Close the environment */
263    if (envp != NULL) {
264        ret_c = envp-&gt;close(envp, 0);
265        if (ret_c != 0) {
266            fprintf(stderr, "environment close failed: %s\n",
267                db_strerror(ret_c));
268            ret = ret_c;
269        }
270    }
271
272    return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
273} </pre>
274      <div class="sect1" lang="en" xml:lang="en">
275        <div class="titlepage">
276          <div>
277            <div>
278              <h2 class="title" style="clear: both"><a id="commitresults"></a>Committing a Transaction</h2>
279            </div>
280          </div>
281        </div>
282        <div class="toc">
283          <dl>
284            <dt>
285              <span class="sect2">
286                <a href="usingtxns.html#nodurabletxn">Non-Durable Transactions</a>
287              </span>
288            </dt>
289          </dl>
290        </div>
291        <p>
292            In order to fully understand what is happening when you commit
293            a transaction, you must first understand a little about what
294            DB is doing with 
295            
296            <span>
297            the logging subsystem. 
298            </span>
299
300            
301
302            Logging causes all database  write operations to be identified in
303
304            <span>logs, and by default these
305            logs are backed by files on disk.  These logs are used to restore your databases 
306            
307            </span>
308
309            
310                    
311            in the event of a system or application failure, so by performing
312            logging, DB ensures the integrity of your data. 
313        </p>
314        <p>
315            Moreover, DB performs <span class="emphasis"><em>write-ahead</em></span>
316            logging. This means that information is written to the logs
317            <span class="emphasis"><em>before</em></span> the actual database 
318            
319            is changed.
320            This means that all write activity performed under the
321            protection of the transaction is noted in the log before
322            the transaction is committed. Be aware, however, that database
323            maintains logs in-memory. If you are backing your logs on
324            disk, the log information will eventually be written to the log
325            files, but while the transaction is on-going the log data may be
326            held only in memory.
327        </p>
328        <p>
329            When you commit a transaction, the following occurs:
330        </p>
331        <div class="itemizedlist">
332          <ul type="disc">
333            <li>
334              <p>
335                    A commit record is written to the log. This
336                    indicates that the modifications made by the
337                    transaction are now permanent. By default, this write is performed synchronously to disk so the
338                    commit record arrives in the log files before any other actions are taken.
339                </p>
340            </li>
341            <li>
342              <p>
343                    Any log information held in memory is (by default)
344                    synchronously written to disk. Note that this requirement can be
345                    relaxed, depending on the type of commit you perform.
346                    See <a class="xref" href="usingtxns.html#nodurabletxn" title="Non-Durable Transactions">Non-Durable Transactions</a> for
347                    more information. 
348                    <span>Also, if you are
349                    maintaining your logs entirely in-memory, then this
350                    step will of course not be taken. To configure your
351                    logging system for in-memory usage, see
352                    <a class="xref" href="logconfig.html#inmemorylogging" title="Configuring In-Memory Logging">Configuring In-Memory Logging</a>.
353                    </span>
354                </p>
355            </li>
356            <li>
357              <p>
358                    All locks held by the transaction are released. This means
359                    that read operations performed by other transactions or
360                    threads of control can now see the modifications without
361                    resorting to uncommitted reads (see <a class="xref" href="isolation.html#dirtyreads" title="Reading Uncommitted Data">Reading Uncommitted Data</a> for more information).
362                </p>
363            </li>
364          </ul>
365        </div>
366        <p>
367            To commit a transaction, you simply call
368            <span><code class="methodname">DB_TXN-&gt;commit()</code>.</span>
369            
370            
371            
372            
373        </p>
374        <p>
375            Notice that committing a transaction does not necessarily cause data
376            modified in your memory cache to be written to the files
377            backing your databases on disk. Dirtied database pages are written
378            for a number of reasons, but a transactional
379            commit is not one of them. The following are the things that can cause a dirtied
380            database page to be written to the backing database file:
381        </p>
382        <div class="itemizedlist">
383          <ul type="disc">
384            <li>
385              <p>
386                    Checkpoints.
387                </p>
388              <p>
389                    Checkpoints cause all dirtied pages currently existing
390                    in the cache to be written to disk, and a checkpoint
391                    record is then written to the logs.  You can run checkpoints
392                    explicitly. For more information on checkpoints,
393                    see <a class="xref" href="filemanagement.html#checkpoints" title="Checkpoints">Checkpoints</a>.
394                </p>
395            </li>
396            <li>
397              <p>
398                    Cache is full.
399                </p>
400              <p>
401                    If the in-memory cache fills up, then dirtied pages
402                    might be written to disk in order to free up space for other
403                    pages that your application needs to use. Note that if
404                    dirtied pages are written to the database files, then
405                    any log records that describe how those pages were 
406                    dirtied are written to disk before the database 
407                    pages are written.
408                </p>
409            </li>
410          </ul>
411        </div>
412        <p>
413            Be aware that because your transaction commit caused database
414            
415            modifications recorded in your logs to be forced to disk, your modifications
416            are by default "persistent" in that they can be recovered in the event of
417            an application or system failure. However, recovery time is
418            gated by how much data has been modified since the last
419            checkpoint, so for applications that perform a lot of writes,
420            you may want to run a checkpoint with some frequency.
421        </p>
422        <p>
423                Note that once you have committed a transaction, the transaction
424                handle that you used for the transaction is no longer valid. To
425                perform database activities under the control of a new
426                transaction, you must obtain a fresh transaction handle.
427              </p>
428        <div class="sect2" lang="en" xml:lang="en">
429          <div class="titlepage">
430            <div>
431              <div>
432                <h3 class="title"><a id="nodurabletxn"></a>Non-Durable Transactions</h3>
433              </div>
434            </div>
435          </div>
436          <p>
437                As previously noted, by default transaction commits are
438                durable because they cause the modifications performed
439                under the transaction to be synchronously recorded in 
440                your on-disk log files.  However, it is possible to use 
441                non-durable transactions.
442            </p>
443          <p>
444                You may want non-durable transactions for performance
445                reasons. For example, you might be using transactions
446                simply for the isolation guarantee. 
447                
448                <span>
449                In this case, you might
450                not want a durability guarantee and so you may want to
451                prevent the disk I/O that normally accompanies a
452                transaction commit.
453                </span>
454                
455            </p>
456          <p>
457                There are several ways to remove the durability guarantee
458                for your transactions:
459            </p>
460          <div class="itemizedlist">
461            <ul type="disc">
462              <li>
463                <p>
464                        Specify          
465                            <span>
466                                <code class="literal">DB_TXN_NOSYNC</code> using the
467                                <code class="methodname">DB_ENV-&gt;set_flags()</code>
468                                
469                            method. 
470                            </span>
471                            
472                         This causes DB to not synchronously force any
473                            <span>
474                                log 
475                            </span>
476                         data to disk upon transaction commit. 
477                         
478                         <span>
479                            That is, the modifications are held entirely
480                            in the in-memory cache and the logging
481                            information is not forced to the filesystem for
482                            long-term storage.
483                         </span>
484
485                         Note, however, that the 
486                            <span>
487                                logging 
488                            </span>
489                         data will eventually make it to the filesystem (assuming no
490                         application or OS crashes) as a part of DB's
491                         management of its logging buffers and/or cache.
492                         </p>
493                <p>
494                            This form of a commit provides a weak durability
495                            guarantee because data loss can occur due to
496                            an application 
497                            or OS crash.
498                    </p>
499                <p>
500                        This behavior is specified on a per-environment
501                        handle basis.  In order for your application to exhibit consistent
502                        behavior, you need to specify this 
503                            <span>flag</span>
504                            
505                        for all of the environment handles used in your application.
506                    </p>
507                <p>
508                        You can achieve this behavior on a transaction by transaction basis by
509                            <span>
510                                specifying <code class="literal">DB_TXN_NOSYNC</code> to the
511                                    <code class="methodname">DB_TXN-&gt;commit()</code>
512                                    
513                                    
514                                method.
515                            </span>
516
517                            
518
519                    </p>
520              </li>
521              <li>
522                <p>
523                        Specify
524                        <span>
525                            <code class="literal">DB_TXN_WRITE_NOSYNC</code> using the
526                                <code class="methodname">DB_ENV-&gt;set_flags()</code>
527                                
528                            method. 
529                            </span>
530
531                            
532
533                            This causes 
534                            <span>
535                                logging 
536                            </span>
537                            data to be synchronously
538                            written to the OS's file system buffers upon
539                            transaction commit. The data will eventually be
540                            written to disk, but this occurs when the
541                            operating system chooses to schedule the
542                            activity; the transaction commit can complete
543                            successfully before this disk I/O is performed
544                            by the OS.
545                       </p>
546                <p>
547                                This  form of commit protects you against application
548                                 crashes, but not against OS
549                                crashes.  This method offers less room for the possibility of data loss than does
550                                <span><code class="literal">DB_TXN_NOSYNC</code>.</span>
551                                
552                    </p>
553                <p>
554                        This behavior is specified on a per-environment
555                        handle basis.  In order for your application to exhibit consistent
556                        behavior, you need to specify this 
557                            <span>flag</span>
558                            
559                        for all of the environment handles used in your application.
560                    </p>
561              </li>
562              <li>
563                <p>
564                        Maintain your logs entirely in-memory. In this
565                        case, your logs are never written to disk. The
566                        result is that you lose all durability guarantees.
567                        See 
568                        <a class="xref" href="logconfig.html#inmemorylogging" title="Configuring In-Memory Logging">Configuring In-Memory Logging</a>
569                        for more information.
570                    </p>
571              </li>
572            </ul>
573          </div>
574        </div>
575      </div>
576    </div>
577    <div class="navfooter">
578      <hr />
579      <table width="100%" summary="Navigation footer">
580        <tr>
581          <td width="40%" align="left"><a accesskey="p" href="envopen.html">Prev</a>��</td>
582          <td width="20%" align="center">��</td>
583          <td width="40%" align="right">��<a accesskey="n" href="abortresults.html">Next</a></td>
584        </tr>
585        <tr>
586          <td width="40%" align="left" valign="top">Opening a Transactional Environment and
587            <span>Database</span>
588            
589            
590        ��</td>
591          <td width="20%" align="center">
592            <a accesskey="h" href="index.html">Home</a>
593          </td>
594          <td width="40%" align="right" valign="top">��Aborting a Transaction</td>
595        </tr>
596      </table>
597    </div>
598  </body>
599</html>
600