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