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>Transactional Cursors and Concurrent Applications</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="txnconcurrency.html" title="Chapter 4. Concurrency" />
11    <link rel="prev" href="isolation.html" title="Isolation" />
12    <link rel="next" href="readmodifywrite.html" title="Read/Modify/Write" />
13  </head>
14  <body>
15    <div class="navheader">
16      <table width="100%" summary="Navigation header">
17        <tr>
18          <th colspan="3" align="center">Transactional Cursors and Concurrent Applications</th>
19        </tr>
20        <tr>
21          <td width="20%" align="left"><a accesskey="p" href="isolation.html">Prev</a> </td>
22          <th width="60%" align="center">Chapter 4. Concurrency</th>
23          <td width="20%" align="right"> <a accesskey="n" href="readmodifywrite.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="txn_ccursor"></a>Transactional Cursors and Concurrent Applications</h2>
33          </div>
34        </div>
35      </div>
36      <div class="toc">
37        <dl>
38          <dt>
39            <span class="sect2">
40              <a href="txn_ccursor.html#cursordirtyreads">Using Cursors with Uncommitted Data</a>
41            </span>
42          </dt>
43        </dl>
44      </div>
45      <p>
46            When you use transactional cursors with a concurrent application, remember that 
47            in the event of a deadlock you must make sure that you close your cursor before you abort and retry your
48            transaction. 
49         </p>
50      <p>
51            Also, remember that when you are using the default isolation level, 
52            every time your cursor reads a record it locks
53            that record until the encompassing transaction is resolved. This
54            means that walking your database with a transactional cursor
55            increases the chance of lock contention. 
56          </p>
57      <p>
58                For this reason, if you must routinely walk your database with a
59                transactional cursor, consider using a reduced isolation level
60                such as read committed. 
61          </p>
62      <div class="sect2" lang="en" xml:lang="en">
63        <div class="titlepage">
64          <div>
65            <div>
66              <h3 class="title"><a id="cursordirtyreads"></a>Using Cursors with Uncommitted Data</h3>
67            </div>
68          </div>
69        </div>
70        <p>
71
72                As described in <a class="xref" href="isolation.html#dirtyreads" title="Reading Uncommitted Data">Reading Uncommitted Data</a> 
73                above, it is possible to relax your transaction's isolation
74                level such that it can read data modified but not yet committed
75                by another transaction. You can configure this when you create
76                your transaction handle, and when you do so then all cursors opened
77                inside that transaction will automatically use uncommitted reads. 
78            </p>
79        <p>
80                You can also do this when you create a cursor handle from within 
81                a serializable transaction.  When you do this, only those 
82                cursors configured for uncommitted reads uses uncommitted reads.
83            </p>
84        <p>
85                    Either way, you must first configure your database
86                     handle to support
87                uncommitted reads before you can configure your transactions or
88                your cursors to use them.
89            </p>
90        <p>
91                The following example shows how to configure an individual cursor handle 
92                to read uncommitted data from within a serializable (full isolation) transaction. 
93                For an example of
94                configuring a transaction to perform uncommitted reads in
95                general, see <a class="xref" href="isolation.html#dirtyreads" title="Reading Uncommitted Data">Reading Uncommitted Data</a>.
96            </p>
97        <pre class="programlisting">#include "db_cxx.h"
98
99...
100                                                                                                                                  
101int main(void)
102{
103    u_int32_t env_flags = DB_CREATE     |  // If the environment does not
104                                           // exist, create it.
105                          DB_INIT_LOCK  |  // Initialize locking
106                          DB_INIT_LOG   |  // Initialize logging
107                          DB_INIT_MPOOL |  // Initialize the cache
108                          DB_INIT_TXN;     // Initialize transactions
109
110    u_int32_t db_flags = DB_CREATE |           // Create the db if it does
111                                               // not exist
112                         DB_AUTO_COMMIT |      // Enable auto commit
113                         DB_READ_UNCOMMITTED;  // Enable uncommitted reads
114
115    Db *dbp = NULL;
116    const char *file_name = "mydb.db";
117
118    std::string envHome("/export1/testEnv");
119    DbEnv myEnv(0);
120
121    Dbc *cursorp = NULL;
122
123    try {
124
125        myEnv.open(envHome.c_str(), env_flags, 0);
126        dbp = new Db(&amp;myEnv, 0);
127        dbp-&gt;open(NULL,       // Txn pointer
128                  file_name,  // File name
129                  NULL,       // Logical db name
130                  DB_BTREE,   // Database type (using btree)
131                  db_flags,   // Open flags
132                  0);         // File mode. Using defaults
133
134        DbTxn *txn = NULL;
135        myEnv.txn_begin(NULL, &amp;txn, 0);
136        try {
137            // Get our cursor. Note that we pass the transaction 
138            // handle here. Note also that we pass the 
139            // DB_READ_UNCOMMITTED flag here so as to cause the
140            // cursor to perform uncommitted reads.
141            db.cursor(txn, &amp;cursorp, DB_READ_UNCOMMITTED); 
142
143            // From here, you perform your cursor reads and writes 
144            // as normal, committing and aborting the transactions as 
145            // is necessary, and testing for deadlock exceptions as 
146            // normal (omitted for brevity). 
147        
148            ... </pre>
149      </div>
150    </div>
151    <div class="navfooter">
152      <hr />
153      <table width="100%" summary="Navigation footer">
154        <tr>
155          <td width="40%" align="left"><a accesskey="p" href="isolation.html">Prev</a> </td>
156          <td width="20%" align="center">
157            <a accesskey="u" href="txnconcurrency.html">Up</a>
158          </td>
159          <td width="40%" align="right"> <a accesskey="n" href="readmodifywrite.html">Next</a></td>
160        </tr>
161        <tr>
162          <td width="40%" align="left" valign="top">Isolation </td>
163          <td width="20%" align="center">
164            <a accesskey="h" href="index.html">Home</a>
165          </td>
166          <td width="40%" align="right" valign="top"Read/Modify/Write</td>
167        </tr>
168      </table>
169    </div>
170  </body>
171</html>
172