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;            &#10;            Store or Database&#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          <dd>
77            <dl>
78              <dt>
79                <span class="sect2">
80                  <a href="txncursor.html#dplcursors">Using Transactional DPL Cursors</a>
81                </span>
82              </dt>
83            </dl>
84          </dd>
85          <dt>
86            <span class="sect1">
87              <a href="txnindices.html">Secondary Indices with Transaction Applications</a>
88            </span>
89          </dt>
90          <dt>
91            <span class="sect1">
92              <a href="maxtxns.html">Configuring the Transaction Subsystem</a>
93            </span>
94          </dt>
95        </dl>
96      </div>
97      <p>
98        Once you have enabled transactions for your environment and your databases,
99        you can use them to protect your database operations. You do this by
100        acquiring a transaction handle and then using that handle for any
101        database operation that you want to participate in that transaction.
102     </p>
103      <p>
104        You obtain a transaction handle using the
105        
106        
107        <span><tt class="methodname">Environment.beginTransaction()</tt> method.</span>
108        
109        
110     </p>
111      <p>
112        Once you have completed all of the operations that you want to include
113        in the transaction, you must commit the transaction using the 
114        
115        
116        <span><tt class="methodname">Transaction.commit()</tt> method.</span>
117        
118        
119        
120    </p>
121      <p>
122        If, for any reason, you want to abandon the transaction, you abort
123        it using 
124        
125        
126        <span><tt class="methodname">Transaction.abort()</tt>.</span>
127        
128        
129
130        
131    </p>
132      <p>
133        Any transaction handle that has been committed or aborted can no longer
134        be used by your application.
135    </p>
136      <p>
137        Finally, you must make sure that all transaction handles are either
138        committed or aborted before closing your databases and environment.
139    </p>
140      <div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
141        <h3 class="title">Note</h3>
142        <p>
143            If you only want to transaction protect a single database write operation, you can use auto commit to 
144            perform the transaction administration. When you use auto commit, you do not need an explicit transaction
145            handle. See <a href="autocommit.html">Auto Commit</a> for more information.
146        </p>
147      </div>
148      <p>
149        For example, the following example opens a transactional-enabled environment and
150        store, obtains a transaction handle, and then performs a write
151        operation under its protection. In the event of any failure in the
152        write operation, the transaction is aborted and the store is left in a
153        state as if no operations had ever been attempted in the first place.
154
155    </p>
156      <pre class="programlisting">package persist.txn;
157                                                                                                                                     
158import com.sleepycat.db.DatabaseException;
159import com.sleepycat.db.Environment;
160import com.sleepycat.db.EnvironmentConfig;
161import com.sleepycat.db.Transaction;
162
163import com.sleepycat.persist.EntityStore;
164import com.sleepycat.persist.StoreConfig;
165
166import java.io.File;
167import java.io.FileNotFoundException;
168                                                                                                                                     
169...
170                                                                                                                                     
171Environment myEnv = null;
172EntityStore store = null;
173
174// Our convenience data accessor class, used for easy access to 
175// EntityClass indexes.
176DataAccessor da;
177
178try {
179    EnvironmentConfig myEnvConfig = new EnvironmentConfig();
180    myEnvConfig.setInitializeCache(true);
181    myEnvConfig.setInitializeLocking(true);
182    myEnvConfig.setInitializeLogging(true);
183    myEnvConfig.setTransactional(true);
184
185    StoreConfig storeConfig = new StoreConfig();
186    storeConfig.setTransactional(true);
187
188    myEnv = new Environment(new File("/my/env/home"),
189                              myEnvConfig);
190
191    EntityStore store = new EntityStore(myEnv, 
192                             "EntityStore", storeConfig);
193
194    da = new DataAccessor(store);
195
196    // Assume that Inventory is an entity class.
197    Inventory theInventory = new Inventory();
198    theInventory.setItemName("Waffles");
199    theInventory.setItemSku("waf23rbni");
200
201    Transaction txn = myEnv.beginTransaction(null, null);
202        
203    try {
204        // Put the object to the store using the transaction handle.
205        da.inventoryBySku.put(txn, theInventory);
206
207        // Commit the transaction. The data is now safely written to the
208        // store.
209        txn.commit();
210    // If there is a problem, abort the transaction
211    } catch (Exception e) {
212        if (txn != null) {
213            txn.abort();
214            txn = null;
215        }
216    }
217
218
219} catch (DatabaseException de) {
220    // Exception handling goes here
221    } catch (FileNotFoundException fnfe) {
222    // Exception handling goes here
223}</pre>
224      <p>
225        The same thing can be done with the base API. In this case, the
226        database in use is left unchanged if the write operation fails:
227    </p>
228      <pre class="programlisting">package db.txn;
229                                                                                                                                     
230import com.sleepycat.db.Database;
231import com.sleepycat.db.DatabaseConfig;
232import com.sleepycat.db.DatabaseEntry;
233import com.sleepycat.db.DatabaseException;
234import com.sleepycat.db.Environment;
235import com.sleepycat.db.EnvironmentConfig;
236import com.sleepycat.db.Transaction;
237
238import java.io.File;
239import java.io.FileNotFoundException;
240                                                                                                                                     
241...
242                                                                                                                                     
243Database myDatabase = null;
244Environment myEnv = null;
245try {
246    EnvironmentConfig myEnvConfig = new EnvironmentConfig();
247    myEnvConfig.setInitializeCache(true);
248    myEnvConfig.setInitializeLocking(true);
249    myEnvConfig.setInitializeLogging(true);
250    myEnvConfig.setTransactional(true);
251
252    myEnv = new Environment(new File("/my/env/home"),
253                              myEnvConfig);
254
255    // Open the database.
256    DatabaseConfig dbConfig = new DatabaseConfig();
257    dbConfig.setTransactional(true);
258    dbConfig.setType(DatabaseType.BTREE);
259    myDatabase = myEnv.openDatabase(null,              // txn handle
260                                    "sampleDatabase",  // db file name
261                                    null,              // db name
262                                    dbConfig);
263    String keyString = "thekey";
264    String dataString = "thedata";
265    DatabaseEntry key = 
266        new DatabaseEntry(keyString.getBytes("UTF-8"));
267    DatabaseEntry data = 
268        new DatabaseEntry(dataString.getBytes("UTF-8"));
269
270    Transaction txn = myEnv.beginTransaction(null, null);
271        
272    try {
273        myDatabase.put(txn, key, data);
274        txn.commit();
275    } catch (Exception e) {
276        if (txn != null) {
277            txn.abort();
278            txn = null;
279        }
280    }
281
282} catch (DatabaseException de) {
283    // Exception handling goes here
284} catch (FileNotFoundException fnfe) {
285    // Exception handling goes here
286} </pre>
287      <div class="sect1" lang="en" xml:lang="en">
288        <div class="titlepage">
289          <div>
290            <div>
291              <h2 class="title" style="clear: both"><a id="commitresults"></a>Committing a Transaction</h2>
292            </div>
293          </div>
294          <div></div>
295        </div>
296        <p>
297            In order to fully understand what is happening when you commit
298            a transaction, you must first understand a little about what
299            DB is doing with 
300            
301            <span>
302            the logging subsystem. 
303            </span>
304
305            
306
307            Logging causes all database <span>or
308                    store</span> write operations to be identified in
309
310            <span>logs, and by default these
311            logs are backed by files on disk.  These logs are used to restore your databases 
312            <span>or store</span>
313            </span>
314
315            
316                    
317            in the event of a system or application failure, so by performing
318            logging, DB ensures the integrity of your data. 
319        </p>
320        <p>
321            Moreover, DB performs <span class="emphasis"><em>write-ahead</em></span>
322            logging. This means that information is written to the logs
323            <span class="emphasis"><em>before</em></span> the actual database 
324            <span>
325                    or store
326            </span>
327            is changed.
328            This means that all write activity performed under the
329            protection of the transaction is noted in the log before
330            the transaction is committed. Be aware, however, that database
331            maintains logs in-memory. If you are backing your logs on
332            disk, the log information will eventually be written to the log
333            files, but while the transaction is on-going the log data may be
334            held only in memory.
335        </p>
336        <p>
337            When you commit a transaction, the following occurs:
338        </p>
339        <div class="itemizedlist">
340          <ul type="disc">
341            <li>
342              <p>
343                    A commit record is written to the log. This
344                    indicates that the modifications made by the
345                    transaction are now permanent. By default, this write is performed synchronously to disk so the
346                    commit record arrives in the log files before any other actions are taken.
347                </p>
348            </li>
349            <li>
350              <p>
351                    Any log information held in memory is (by default)
352                    synchronously written to disk. Note that this requirement can be
353                    relaxed, depending on the type of commit you perform.
354                    See <a href="usingtxns.html#nodurabletxn">Non-Durable Transactions</a> for
355                    more information. 
356                    <span>Also, if you are
357                    maintaining your logs entirely in-memory, then this
358                    step will of course not be taken. To configure your
359                    logging system for in-memory usage, see
360                    <a href="logconfig.html#inmemorylogging">Configuring In-Memory Logging</a>.
361                    </span>
362                </p>
363            </li>
364            <li>
365              <p>
366                    All locks held by the transaction are released. This means
367                    that read operations performed by other transactions or
368                    threads of control can now see the modifications without
369                    resorting to uncommitted reads (see <a href="isolation.html#dirtyreads">Reading Uncommitted Data</a> for more information).
370                </p>
371            </li>
372          </ul>
373        </div>
374        <p>
375            To commit a transaction, you simply call
376            
377            
378            <span><tt class="methodname">Transaction.commit()</tt>.</span>
379            
380            
381        </p>
382        <p>
383            Notice that committing a transaction does not necessarily cause data
384            modified in your memory cache to be written to the files
385            backing your databases on disk. Dirtied database pages are written
386            for a number of reasons, but a transactional
387            commit is not one of them. The following are the things that can cause a dirtied
388            database page to be written to the backing database file:
389        </p>
390        <div class="itemizedlist">
391          <ul type="disc">
392            <li>
393              <p>
394                    Checkpoints.
395                </p>
396              <p>
397                    Checkpoints cause all dirtied pages currently existing
398                    in the cache to be written to disk, and a checkpoint
399                    record is then written to the logs.  You can run checkpoints
400                    explicitly. For more information on checkpoints,
401                    see <a href="filemanagement.html#checkpoints">Checkpoints</a>.
402                </p>
403            </li>
404            <li>
405              <p>
406                    Cache is full.
407                </p>
408              <p>
409                    If the in-memory cache fills up, then dirtied pages
410                    might be written to disk in order to free up space for other
411                    pages that your application needs to use. Note that if
412                    dirtied pages are written to the database files, then
413                    any log records that describe how those pages were 
414                    dirtied are written to disk before the database 
415                    pages are written.
416                </p>
417            </li>
418          </ul>
419        </div>
420        <p>
421            Be aware that because your transaction commit caused database
422            <span>
423                    or store
424            </span>
425            modifications recorded in your logs to be forced to disk, your modifications
426            are by default "persistent" in that they can be recovered in the event of
427            an application or system failure. However, recovery time is
428            gated by how much data has been modified since the last
429            checkpoint, so for applications that perform a lot of writes,
430            you may want to run a checkpoint with some frequency.
431        </p>
432        <p>
433                Note that once you have committed a transaction, the transaction
434                handle that you used for the transaction is no longer valid. To
435                perform database activities under the control of a new
436                transaction, you must obtain a fresh transaction handle.
437              </p>
438        <div class="sect2" lang="en" xml:lang="en">
439          <div class="titlepage">
440            <div>
441              <div>
442                <h3 class="title"><a id="nodurabletxn"></a>Non-Durable Transactions</h3>
443              </div>
444            </div>
445            <div></div>
446          </div>
447          <p>
448                As previously noted, by default transaction commits are
449                durable because they cause the modifications performed
450                under the transaction to be synchronously recorded in 
451                your on-disk log files.  However, it is possible to use 
452                non-durable transactions.
453            </p>
454          <p>
455                You may want non-durable transactions for performance
456                reasons. For example, you might be using transactions
457                simply for the isolation guarantee. 
458                
459                <span>
460                In this case, you might
461                not want a durability guarantee and so you may want to
462                prevent the disk I/O that normally accompanies a
463                transaction commit.
464                </span>
465                
466            </p>
467          <p>
468                There are several ways to remove the durability guarantee
469                for your transactions:
470            </p>
471          <div class="itemizedlist">
472            <ul type="disc">
473              <li>
474                <p>
475                        Specify          
476                            
477                            <span>
478                                <tt class="literal">true</tt> to the
479                                <tt class="methodname">EnvironmentConfig.setTxnNoSync()</tt>
480                                
481                                method.
482                            </span>
483                         This causes DB to not synchronously force any
484                            <span>
485                                log 
486                            </span>
487                         data to disk upon transaction commit. 
488                         
489                         <span>
490                            That is, the modifications are held entirely
491                            in the in-memory cache and the logging
492                            information is not forced to the filesystem for
493                            long-term storage.
494                         </span>
495
496                         Note, however, that the 
497                            <span>
498                                logging 
499                            </span>
500                         data will eventually make it to the filesystem (assuming no
501                         application or OS crashes) as a part of DB's
502                         management of its logging buffers and/or cache.
503                         </p>
504                <p>
505                            This form of a commit provides a weak durability
506                            guarantee because data loss can occur due to
507                            an application<span>, JVM,</span> 
508                            or OS crash.
509                    </p>
510                <p>
511                        This behavior is specified on a per-environment
512                        handle basis.  In order for your application to exhibit consistent
513                        behavior, you need to specify this 
514                            
515                            <span>method</span>
516                        for all of the environment handles used in your application.
517                    </p>
518                <p>
519                        You can achieve this behavior on a transaction by transaction basis by
520                            
521
522                            <span>
523                                using <tt class="methodname">Transaction.commitNoSync()</tt>
524                                      
525                                to commit your transaction, or by specifying <tt class="literal">true</tt> to the 
526                                <tt class="methodname">TransactionConfig.setNoSync()</tt> method when starting the
527                                transaction.
528                            </span>
529
530                    </p>
531              </li>
532              <li>
533                <p>
534                        Specify
535                        
536
537                            <span>
538                                <tt class="literal">true</tt> to the
539                                <tt class="methodname">EnvironmentConfig.setTxnWriteNoSync()</tt>
540                                method.
541                            </span>
542
543                            This causes 
544                            <span>
545                                logging 
546                            </span>
547                            data to be synchronously
548                            written to the OS's file system buffers upon
549                            transaction commit. The data will eventually be
550                            written to disk, but this occurs when the
551                            operating system chooses to schedule the
552                            activity; the transaction commit can complete
553                            successfully before this disk I/O is performed
554                            by the OS.
555                       </p>
556                <p>
557                                This  form of commit protects you against application
558                                <span>and JVM</span> crashes, but not against OS
559                                crashes.  This method offers less room for the possibility of data loss than does
560                                
561                                <span><tt class="methodname">EnvironmentConfig.setTxnNoSync()</tt>.</span>
562                    </p>
563                <p>
564                        This behavior is specified on a per-environment
565                        handle basis.  In order for your application to exhibit consistent
566                        behavior, you need to specify this 
567                            
568                            <span>method</span>
569                        for all of the environment handles used in your application.
570                    </p>
571                <p>
572                        You can achieve this behavior on a transaction by transaction basis by
573                            <span>
574                                using <tt class="methodname">Transaction.commitWriteNoSync()</tt>
575                                to commit your transaction, or by specifying <tt class="literal">true</tt> to
576                                <tt class="methodname">TransactionConfig.setWriteNoSync()</tt> method when starting the
577                                transaction.
578                            </span>
579                    </p>
580              </li>
581              <li>
582                <p>
583                        Maintain your logs entirely in-memory. In this
584                        case, your logs are never written to disk. The
585                        result is that you lose all durability guarantees.
586                        See 
587                        <a href="logconfig.html#inmemorylogging">Configuring In-Memory Logging</a>
588                        for more information.
589                    </p>
590              </li>
591            </ul>
592          </div>
593        </div>
594      </div>
595    </div>
596    <div class="navfooter">
597      <hr />
598      <table width="100%" summary="Navigation footer">
599        <tr>
600          <td width="40%" align="left"><a accesskey="p" href="envopen.html">Prev</a> </td>
601          <td width="20%" align="center">
602            <a accesskey="u" href="index.html">Up</a>
603          </td>
604          <td width="40%" align="right"> <a accesskey="n" href="abortresults.html">Next</a></td>
605        </tr>
606        <tr>
607          <td width="40%" align="left" valign="top">Opening a Transactional Environment and
608            
609            Store or Database
610            
611         </td>
612          <td width="20%" align="center">
613            <a accesskey="h" href="index.html">Home</a>
614          </td>
615          <td width="40%" align="right" valign="top"> Aborting a Transaction</td>
616        </tr>
617      </table>
618    </div>
619  </body>
620</html>
621