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