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>DPL Transaction Example</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="wrapup.html" title="Chapter��6.��Summary and Examples" />
11    <link rel="previous" href="txnexample_java.html" title="Base API Transaction Example" />
12    <link rel="next" href="inmem_txnexample_java.html" title="Base API In-Memory Transaction Example" />
13  </head>
14  <body>
15    <div class="navheader">
16      <table width="100%" summary="Navigation header">
17        <tr>
18          <th colspan="3" align="center">DPL Transaction Example</th>
19        </tr>
20        <tr>
21          <td width="20%" align="left"><a accesskey="p" href="txnexample_java.html">Prev</a>��</td>
22          <th width="60%" align="center">Chapter��6.��Summary and Examples</th>
23          <td width="20%" align="right">��<a accesskey="n" href="inmem_txnexample_java.html">Next</a></td>
24        </tr>
25      </table>
26      <hr />
27    </div>
28    <div class="sect1" lang="en" xml:lang="en">
29      <div class="titlepage">
30        <div>
31          <div>
32            <h2 class="title" style="clear: both"><a id="txnexample_dpl"></a>DPL Transaction Example</h2>
33          </div>
34        </div>
35        <div></div>
36      </div>
37      <p>
38        The following Java code provides a fully functional example of a
39        multi-threaded transactional DB application using the DPL. 
40        This example is nearly identical to the example provided in the
41        previous section, except that it uses an entity class and entity
42        store to manage its data.
43    </p>
44      <p>
45            As is the case with the previous examples, this example opens
46            an environment and then an entity store. It then creates 
47            5 threads, each of which writes 500 records to the database.
48            The primary key for these writes are based on pre-determined
49            integers, while the data is randomly generated data. 
50            This means that the actual data is arbitrary and therefore uninteresting; 
51            we picked it only because it requires minimum code to implement and therefore will 
52        stay out of the way of the main points of this example.
53    </p>
54      <p>
55        Each thread writes 10 records under a single transaction
56        before committing and writing another 10 (this is repeated 50
57        times). At the end of each transaction, but before committing, each
58        thread calls a function that uses a cursor to read every record in
59        the database. We do this in order to make some points about
60        database reads in a transactional environment.
61    </p>
62      <p>
63        Of course, each writer thread performs deadlock detection as
64        described in this manual. In addition, normal recovery is performed
65        when the environment is opened.
66    </p>
67      <p>
68        To implement this example, we need three classes:    
69    </p>
70      <div class="itemizedlist">
71        <ul type="disc">
72          <li>
73            <p>
74                <tt class="literal">TxnGuide.java</tt>
75            </p>
76            <p>
77                This is the main class for the application. It performs
78                environment and store management, spawns threads, and
79                creates the data that is placed in the database.  See <a href="txnexample_dpl.html#txnguideexample_dpl">TxnGuide.java</a> for implementation details.
80            </p>
81          </li>
82          <li>
83            <p>
84                <tt class="literal">StoreWriter.java</tt>
85            </p>
86            <p>
87                This class extends <tt class="literal">java.lang.Thread</tt>, and
88                as such it is our thread implementation.  It is responsible
89                for actually reading and writing store. It also
90                performs all of our transaction management.  See <a href="txnexample_dpl.html#storewriter">StoreWriter.java</a> for
91                implementation details.
92            </p>
93          </li>
94          <li>
95            <p>
96                <tt class="literal">PayloadDataEntity.java</tt>
97            </p>
98            <p>
99                This is an entity class used to encapsulate several data
100                fields.  See <a href="txnexample_dpl.html#payloaddataentity">PayloadDataEntity.java</a> for
101                implementation details.
102            </p>
103          </li>
104        </ul>
105      </div>
106      <div class="sect2" lang="en" xml:lang="en">
107        <div class="titlepage">
108          <div>
109            <div>
110              <h3 class="title"><a id="txnguideexample_dpl"></a>TxnGuide.java</h3>
111            </div>
112          </div>
113          <div></div>
114        </div>
115        <p>
116            The main class in our example application is used to open and
117            close our environment and store. It also spawns all the
118            threads that we need. We start with the normal series
119            of Java package and import statements, followed by our class
120            declaration:
121        </p>
122        <pre class="programlisting">// File TxnGuideDPL.java
123
124package persist.txn;
125
126import com.sleepycat.db.DatabaseConfig;
127import com.sleepycat.db.DatabaseException;
128import com.sleepycat.db.DatabaseType;
129import com.sleepycat.db.LockDetectMode;
130
131import com.sleepycat.db.Environment;
132import com.sleepycat.db.EnvironmentConfig;
133
134import com.sleepycat.persist.EntityStore;
135import com.sleepycat.persist.StoreConfig;
136
137import java.io.File;
138import java.io.FileNotFoundException;
139
140public class TxnGuideDPL { </pre>
141        <p>
142    Next we declare our class' private data members. Mostly these are used
143    for constants such as the name of the database that we are opening and
144    the number of threads that we are spawning. However, we also declare
145    our environment and database handles here.
146</p>
147        <pre class="programlisting">    private static String myEnvPath = "./";
148    private static String storeName = "exampleStore";
149
150    // Handles
151    private static EntityStore myStore = null;
152                private static Environment myEnv = null;
153    private static final int NUMTHREADS = 5; </pre>
154        <p>
155    Next, we implement our <tt class="function">usage()</tt> method. This
156    application optionally accepts a single command line argument which is
157    used to identify the environment home directory.
158</p>
159        <pre class="programlisting">    private static void usage() {
160        System.out.println("TxnGuideDPL [-h &lt;env directory&gt;]");
161        System.exit(-1);
162    } </pre>
163        <p>
164    Now we implement our <tt class="function">main()</tt> method. This method
165    simply calls the methods to parse the command line arguments and open
166    the environment and store. It also creates and then joins the store writer
167    threads.
168</p>
169        <pre class="programlisting">    public static void main(String args[]) {
170        try {
171            // Parse the arguments list
172            parseArgs(args);
173            // Open the environment and store
174            openEnv();
175
176            // Start the threads
177            StoreWriter[] threadArray;
178            threadArray = new StoreWriter[NUMTHREADS];
179            for (int i = 0; i &lt; NUMTHREADS; i++) {
180                threadArray[i] = new StoreWriter(myEnv, myStore);
181                threadArray[i].start();
182            }
183
184            for (int i = 0; i &lt; NUMTHREADS; i++) {
185                threadArray[i].join();
186            }
187        } catch (Exception e) {
188            System.err.println("TxnGuideDPL: " + e.toString());
189            e.printStackTrace();
190        } finally {
191            closeEnv();
192        }
193        System.out.println("All done.");
194    } </pre>
195        <p>
196    Next we implement <tt class="function">openEnv()</tt>. This method is used
197    to open the environment and then an entity store in that environment. Along
198    the way, we make sure that every handle is free-threaded, and that the
199    transactional subsystem is correctly initialized. Because this is a
200    concurrent application, we also declare how we want deadlock detection
201    to be performed. In this case, we use DB's internal block detector
202    to determine whether a deadlock has occurred when a thread attempts to
203    acquire a lock. We also indicate that we want the deadlocked thread
204    with the <span class="emphasis"><em>youngest</em></span> lock to receive deadlock
205    notification.
206</p>
207        <p>
208    Notice that we also cause normal recovery to be run when we open the
209    environment. This is the standard and recommended thing to do whenever
210    you start up a transactional application.
211</p>
212        <p>
213    Finally, notice that we open the database such that it supports
214    uncommitted reads. We do this so that some cursor activity later in
215    this example can read uncommitted data.  If we did not do this, then
216    our <tt class="methodname">countObjects()</tt> method described later in
217    this example would cause our thread to self-deadlock. This is because
218    the cursor could not be opened to support uncommitted reads (that flag
219    on the cursor open would, in fact, be silently ignored).
220</p>
221        <pre class="programlisting">    private static void openEnv() throws DatabaseException {
222        System.out.println("opening env and store");
223
224        // Set up the environment.
225        EnvironmentConfig myEnvConfig = new EnvironmentConfig();
226        myEnvConfig.setAllowCreate(true);
227        myEnvConfig.setInitializeCache(true);
228        myEnvConfig.setInitializeLocking(true);
229        myEnvConfig.setInitializeLogging(true);
230        myEnvConfig.setRunRecovery(true);
231        myEnvConfig.setTransactional(true);
232        // EnvironmentConfig.setThreaded(true) is the default behavior 
233        // in Java, so we do not have to do anything to cause the
234        // environment handle to be free-threaded.
235
236        // Indicate that we want db to internally perform deadlock 
237        // detection. Also indicate that the transaction that has
238        // performed the least amount of write activity to
239        // receive the deadlock notification, if any.
240        myEnvConfig.setLockDetectMode(LockDetectMode.MINWRITE);
241
242        // Set up the entity store
243        StoreConfig myStoreConfig = new StoreConfig();
244        myStoreConfig.setAllowCreate(true);
245        myStoreConfig.setTransactional(true);
246
247        // Need a DatabaseConfig object so as to set uncommitted read
248        // support.
249        DatabaseConfig myDbConfig = new DatabaseConfig();
250        myDbConfig.setType(DatabaseType.BTREE);
251        myDbConfig.setAllowCreate(true);
252        myDbConfig.setTransactional(true);
253        myDbConfig.setReadUncommitted(true);
254
255        try {
256            // Open the environment
257            myEnv = new Environment(new File(myEnvPath),    // Env home
258                                    myEnvConfig);
259
260            // Open the store
261            myStore = new EntityStore(myEnv, storeName, myStoreConfig);
262
263            // Set the DatabaseConfig object, so that the underlying
264            // database is configured for uncommitted reads.
265            myStore.setPrimaryConfig(PayloadDataEntity.class, myDbConfig);
266        } catch (FileNotFoundException fnfe) {
267            System.err.println("openEnv: " + fnfe.toString());
268            System.exit(-1);
269        }
270    } </pre>
271        <p>
272    Finally, we implement the methods used to close our environment and
273    databases, parse the command line arguments, and provide our class
274    constructor. This is fairly standard code and it is mostly
275    uninteresting from the perspective of this manual. We include it here
276    purely for the purpose of completeness.
277</p>
278        <pre class="programlisting">    private static void closeEnv() {
279        System.out.println("Closing env and store");
280        if (myStore != null ) {
281            try {
282                myStore.close();
283            } catch (DatabaseException e) {
284                System.err.println("closeEnv: myStore: " +
285                    e.toString());
286                e.printStackTrace();
287            }
288        }
289
290        if (myEnv != null ) {
291            try {
292                myEnv.close();
293            } catch (DatabaseException e) {
294                System.err.println("closeEnv: " + e.toString());
295                e.printStackTrace();
296            }
297        }
298    }
299
300    private TxnGuideDPL() {}
301
302    private static void parseArgs(String args[]) {
303        int nArgs = args.length;
304        for(int i = 0; i &lt; args.length; ++i) {
305            if (args[i].startsWith("-")) {
306                switch(args[i].charAt(1)) {
307                    case 'h':
308                        if (i &lt; nArgs - 1) {
309                            myEnvPath = new String(args[++i]);
310                        }
311                    break;
312                    default:
313                        usage();
314                }
315            }
316        }
317    }
318} </pre>
319      </div>
320      <div class="sect2" lang="en" xml:lang="en">
321        <div class="titlepage">
322          <div>
323            <div>
324              <h3 class="title"><a id="payloaddataentity"></a>PayloadDataEntity.java</h3>
325            </div>
326          </div>
327          <div></div>
328        </div>
329        <p>
330    Before we show the implementation of the store writer thread, we
331    need to show the class that we will be placing into the store. This
332    class is fairly minimal. It simply allows you to store and retrieve an
333    <tt class="literal">int</tt>, a <tt class="literal">String</tt>, and a
334    <tt class="literal">double</tt>.  The <tt class="literal">int</tt> is our primary key.
335</p>
336        <pre class="programlisting">package persist.txn;
337import com.sleepycat.persist.model.Entity;
338import com.sleepycat.persist.model.PrimaryKey;
339import static com.sleepycat.persist.model.Relationship.*;
340
341@Entity
342public class PayloadDataEntity {
343    @PrimaryKey
344    private int oID;
345
346    private String threadName;
347
348    private double doubleData;
349
350    PayloadDataEntity() {}
351
352    public double getDoubleData() { return doubleData; }
353    public int getID() { return oID; }
354    public String getThreadName() { return threadName; }
355
356    public void setDoubleData(double dd) { doubleData = dd; }
357    public void setID(int id) { oID = id; }
358    public void setThreadName(String tn) { threadName = tn; }
359} </pre>
360      </div>
361      <div class="sect2" lang="en" xml:lang="en">
362        <div class="titlepage">
363          <div>
364            <div>
365              <h3 class="title"><a id="storewriter"></a>StoreWriter.java</h3>
366            </div>
367          </div>
368          <div></div>
369        </div>
370        <p>
371            <tt class="literal">StoreWriter.java</tt> provides the implementation
372            for our entity store writer thread. It is responsible for: 
373        </p>
374        <div class="itemizedlist">
375          <ul type="disc">
376            <li>
377              <p>
378                    All transaction management.
379                </p>
380            </li>
381            <li>
382              <p>
383                    Responding to deadlock exceptions.
384                </p>
385            </li>
386            <li>
387              <p>
388                    Providing data to be stored in the entity store.
389                </p>
390            </li>
391            <li>
392              <p>
393                    Writing the data to the store.
394                </p>
395            </li>
396          </ul>
397        </div>
398        <p>
399                In order to show off some of the ACID properties provided
400                by DB's transactional support,
401                <tt class="literal">StoreWriter.java</tt> does some things in a less
402                efficient way than you would probably decide to use in a
403                true production application. First, it groups 10 database
404                writes together in a single transaction when you could just
405                as easily perform one write for each transaction. If you
406                did this, you could use auto commit for the individual
407                database writes, which means your code would be slightly
408                simpler and you would run a <span class="emphasis"><em>much</em></span>
409                smaller chance of encountering blocked and deadlocked
410                operations. However, by doing things this way, we are able
411                to show transactional atomicity, as well as deadlock
412                handling.
413            </p>
414        <p>
415                To begin, we provide the usual package and import statements, and we declare our class:
416            </p>
417        <pre class="programlisting">package persist.txn;
418
419import com.sleepycat.db.CursorConfig;
420import com.sleepycat.db.DatabaseException;
421import com.sleepycat.db.DeadlockException;
422import com.sleepycat.db.Environment;
423import com.sleepycat.db.Transaction;
424
425import com.sleepycat.persist.EntityCursor;
426import com.sleepycat.persist.EntityStore;
427import com.sleepycat.persist.PrimaryIndex;
428
429import java.util.Iterator;
430import java.util.Random;
431import java.io.UnsupportedEncodingException;
432
433public class StoreWriter extends Thread
434{ </pre>
435        <p>
436    Next we declare our private data members. Notice that we get handles
437    for the environment and the entity store.  The random number generator 
438    that we instantiate is used
439    to generate unique data for storage in the database.  Finally, the
440    <tt class="literal">MAX_RETRY</tt> variable is used to define how many times
441    we will retry a transaction in the face of a deadlock. 
442</p>
443        <pre class="programlisting">    private EntityStore myStore = null;
444    private Environment myEnv = null;
445    private PrimaryIndex&lt;Integer,PayloadDataEntity&gt; pdKey;
446    private Random generator = new Random();
447    private boolean passTxn = false;
448
449    private static final int MAX_RETRY = 20; </pre>
450        <p>
451        Next we implement our class constructor. The most interesting thing about our constructor is
452        that we use it to obtain our entity class's primary index.
453    </p>
454        <pre class="programlisting">    // Constructor. Get our handles from here
455    StoreWriter(Environment env, EntityStore store)
456
457        throws DatabaseException {
458        myStore = store;
459        myEnv = env;
460
461        // Open the data accessor. This is used to store persistent
462        // objects.
463        pdKey = myStore.getPrimaryIndex(Integer.class,
464                    PayloadDataEntity.class);
465    } </pre>
466        <p>
467    Now we implement our thread's <tt class="methodname">run()</tt> method.
468    This is the method that is run when <tt class="classname">StoreWriter</tt>
469    threads are started in the main program (see <a href="txnexample_dpl.html#txnguideexample_dpl">TxnGuide.java</a>).
470</p>
471        <pre class="programlisting">    // Thread method that writes a series of records
472    // to the database using transaction protection.
473    // Deadlock handling is demonstrated here.
474    public void run () { </pre>
475        <p>
476    The first thing we do is get a <tt class="literal">null</tt> transaction
477    handle before going into our main loop. We also begin the top transaction loop here that causes our application to
478    perform 50 transactions.
479</p>
480        <pre class="programlisting">        Transaction txn = null;
481
482        // Perform 50 transactions
483        for (int i=0; i&lt;50; i++) { </pre>
484        <p>
485    Next we declare a <tt class="literal">retry</tt> variable. This is used to
486    determine whether a deadlock should result in our retrying the
487    operation. We also declare a  <tt class="literal">retry_count</tt> variable
488    that is used to make sure we do not retry a transaction forever in the
489    unlikely event that the thread is unable to ever get a necessary lock.
490    (The only thing that might cause this is if some other thread dies
491    while holding an important lock. This is the only code that we have to
492    guard against that because the simplicity of this application makes it
493    highly unlikely that it will ever occur.)
494</p>
495        <pre class="programlisting">           boolean retry = true;
496           int retry_count = 0;
497           // while loop is used for deadlock retries
498           while (retry) { </pre>
499        <p>
500    Now we go into the <tt class="literal">try</tt> block that we use for
501    deadlock detection. We also begin our transaction here.
502</p>
503        <pre class="programlisting">                // try block used for deadlock detection and
504                // general exception handling
505                try {
506
507                    // Get a transaction
508                    txn = myEnv.beginTransaction(null, null); </pre>
509        <p>
510        Now we write 10 objects under the transaction that we have just begun. 
511        By combining multiple writes together under a single transaction,
512        we increase the likelihood that a deadlock will occur. Normally,
513        you want to reduce the potential for a deadlock and in this case
514        the way to do that is to perform a single write per transaction. In
515        other words, we <span class="emphasis"><em>should</em></span> be using auto commit to
516        write to our database for this workload.
517    </p>
518        <p>
519        However, we want to show deadlock handling and by performing
520        multiple writes per transaction we can actually observe deadlocks
521        occurring. We also want to underscore the idea that you can
522        combing multiple database operations together in a single atomic
523        unit of work. So for our example, we do the (slightly) wrong thing.
524    </p>
525        <pre class="programlisting">
526
527                    // Write 10 PayloadDataEntity objects to the 
528                    // store for each transaction
529                    for (int j = 0; j &lt; 10; j++) {
530                        // Instantiate an object
531                        PayloadDataEntity pd = new PayloadDataEntity();
532
533                        // Set the Object ID. This is used as the 
534                        // primary key.
535                        pd.setID(i + j);
536
537                        // The thread name is used as a secondary key, and
538                        // it is retrieved by this class's getName() 
539                        // method.
540                        pd.setThreadName(getName());
541
542                        // The last bit of data that we use is a double
543                        // that we generate randomly. This data is not
544                        // indexed.
545                        pd.setDoubleData(generator.nextDouble());
546
547                        // Do the put
548                        pdKey.put(txn, pd);
549                    } </pre>
550        <p>
551        Having completed the inner database write loop, we could simply
552        commit the transaction and continue on to the next block of 10
553        writes. However, we want to first illustrate a few points about
554        transactional processing so instead we call our
555        <tt class="function">countObjects()</tt> method before calling the transaction
556        commit. <tt class="function">countObjects()</tt> uses a cursor to read every
557        object in the entity store and return a count of the number of objects
558        that it found. 
559    </p>
560        <p>
561        Because 
562        <tt class="function">countObjects()</tt> 
563        reads every object in the store, if used incorrectly the thread
564        will self-deadlock.  The writer thread has just written 500 objects
565        to the database, but because the transaction used for that write
566        has not yet been committed, each of those 500 objects are still
567        locked by the thread's transaction. If we then simply run a
568        non-transactional cursor over the store from within the same
569        thread that has locked those 500 objects, the cursor will
570        block when it tries to read one of those transactional
571        protected records. The thread immediately stops operation at that
572        point while the cursor waits for the read lock it has
573        requested.  Because that read lock will never be released (the thread
574        can never make any forward progress), this represents a
575        self-deadlock for the thread.
576    </p>
577        <p>
578        There are three ways to prevent this self-deadlock:
579    </p>
580        <div class="orderedlist">
581          <ol type="1">
582            <li>
583              <p>
584                We can move the call to
585                <tt class="function">countObjects()</tt> to a point after the
586                thread's transaction has committed. 
587            </p>
588            </li>
589            <li>
590              <p>
591                We can allow <tt class="function">countObjects()</tt> to
592                operate under the same transaction as all of the writes
593                were performed.
594            </p>
595            </li>
596            <li>
597              <p>
598                We can reduce our isolation guarantee for the application
599                by allowing uncommitted reads.
600            </p>
601            </li>
602          </ol>
603        </div>
604        <p>
605        For this example, we choose to use option 3 (uncommitted reads) to avoid
606        the deadlock. This means that we have to open our underlying database such
607        that it supports uncommitted reads, and we have to open our cursor handle
608        so that it knows to perform uncommitted reads.
609    </p>
610        <pre class="programlisting">                    // commit
611                    System.out.println(getName() + " : committing txn : " + i);
612                    System.out.println(getName() + " : Found " +
613                        countObjects(txn) + " objects in the store."); </pre>
614        <p>
615    Having performed this somewhat inelegant counting of the objects in the
616    database, we can now commit the transaction.
617</p>
618        <pre class="programlisting">                    try {
619                        txn.commit();
620                        txn = null;
621                    } catch (DatabaseException e) {
622                        System.err.println("Error on txn commit: " +
623                            e.toString());
624                    }
625                    retry = false; </pre>
626        <p>
627    If all goes well with the commit, we are done and we can move on to the
628    next batch of 10 objects to add to the store. However, in the event
629    of an error, we must handle our exceptions correctly. The first of
630    these is a deadlock exception. In the event of a deadlock, we want to
631    abort and retry the transaction, provided that we have not already
632    exceeded our retry limit for this transaction.
633</p>
634        <pre class="programlisting">                } catch (DeadlockException de) {
635                    System.out.println("################# " + getName() +
636                        " : caught deadlock");
637                    // retry if necessary
638                    if (retry_count &lt; MAX_RETRY) {
639                        System.err.println(getName() +
640                            " : Retrying operation.");
641                        retry = true;
642                        retry_count++;
643                    } else {
644                        System.err.println(getName() +
645                            " : out of retries. Giving up.");
646                        retry = false;
647                    } </pre>
648        <p>
649    In the event of a standard, non-specific database exception, we simply
650    log the exception and then give up (the transaction is not retried).
651</p>
652        <pre class="programlisting">                } catch (DatabaseException e) {
653                    // abort and don't retry
654                    retry = false;
655                    System.err.println(getName() +
656                        " : caught exception: " + e.toString());
657                    System.err.println(getName() +
658                        " : errno: " + e.getErrno());
659                    e.printStackTrace();  </pre>
660        <p>
661    And, finally, we always abort the transaction if the transaction handle
662    is not null. Note that immediately after committing our transaction, we
663    set the transaction handle to null to guard against aborting a
664    transaction that has already been committed.
665</p>
666        <pre class="programlisting">                } finally {
667                    if (txn != null) {
668                        try {
669                            txn.abort();
670                        } catch (Exception e) {
671                            System.err.println("Error aborting txn: " +
672                                e.toString());
673                            e.printStackTrace();
674                        }
675                    }
676                }
677            }
678        }
679    } </pre>
680        <p>
681    The final piece of our <tt class="classname">StoreWriter</tt> class is the
682    <tt class="methodname">countObjects()</tt> implementation. Notice how in
683    this example we open the cursor such that it performs uncommitted
684    reads:
685</p>
686        <pre class="programlisting">    // A method that counts every object in the store.
687
688    private int countObjects(Transaction txn)  throws DatabaseException {
689        int count = 0;
690
691        CursorConfig cc = new CursorConfig();
692        // This is ignored if the store is not opened with uncommitted read
693        // support.
694        cc.setReadUncommitted(true);
695        EntityCursor&lt;PayloadDataEntity&gt; cursor = pdKey.entities(txn, cc);
696
697        try {
698            for (PayloadDataEntity pdi : cursor) {
699                    count++;
700            }
701        } finally {
702            if (cursor != null) {
703                cursor.close();
704            }
705        }
706
707        return count;
708
709    }
710} </pre>
711      </div>
712      <p>
713    This completes our transactional example. If you would like to
714    experiment with this code, you can find the example in the following
715    location in your DB distribution:
716</p>
717      <pre class="programlisting"><span class="emphasis"><em>DB_INSTALL</em></span>/examples_java/src/persist/txn</pre>
718    </div>
719    <div class="navfooter">
720      <hr />
721      <table width="100%" summary="Navigation footer">
722        <tr>
723          <td width="40%" align="left"><a accesskey="p" href="txnexample_java.html">Prev</a>��</td>
724          <td width="20%" align="center">
725            <a accesskey="u" href="wrapup.html">Up</a>
726          </td>
727          <td width="40%" align="right">��<a accesskey="n" href="inmem_txnexample_java.html">Next</a></td>
728        </tr>
729        <tr>
730          <td width="40%" align="left" valign="top">Base API Transaction Example��</td>
731          <td width="20%" align="center">
732            <a accesskey="h" href="index.html">Home</a>
733          </td>
734          <td width="40%" align="right" valign="top">��Base API In-Memory Transaction Example</td>
735        </tr>
736      </table>
737    </div>
738  </body>
739</html>
740