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 &lt;stdio.h&gt;
98#include &lt;stdlib.h&gt;
99
100#include "db.h"
101
102int
103main(void)
104{
105    DB *dbp;
106    DBC *cursorp;
107    DB_ENV *envp;
108    DB_TXN *txn;
109    int ret, c_ret;
110    char *replacementString = "new string";
111
112    dbp = NULL;
113    envp = NULL;
114    txn = NULL;
115
116    /* Open the environment */
117    ret = db_env_create(&amp;envp, 0);
118    if (ret != 0) {
119        fprintf(stderr, "Error creating environment handle: %s\n",
120            db_strerror(ret));
121        return (EXIT_FAILURE);
122    }
123                                                                                                                                  
124    env_flags = DB_CREATE |    /* Create the environment if it does 
125                                * not already exist. */
126                DB_INIT_TXN  | /* Initialize transactions */
127                DB_INIT_LOCK | /* Initialize locking. */
128                DB_INIT_LOG  | /* Initialize logging */
129                DB_INIT_MPOOL; /* Initialize the in-memory cache. */
130
131    ret = envp-&gt;open(envp, db_home_dir, env_flags, 0);
132    if (ret != 0) {
133        fprintf(stderr, "Error opening environment: %s\n",
134            db_strerror(ret));
135        goto err;
136    }
137
138    /* Initialize the DB handle */
139    ret = db_create(&amp;dbp, envp, 0);
140    if (ret != 0) {
141        envp-&gt;err(envp, ret, "Database creation failed");
142        goto err;
143    }
144
145    db_flags = DB_CREATE |             /* Create the db if it does not 
146                                        * exist */
147               DB_AUTO_COMMIT |        /* Enable auto commit */
148               DB_READ_UNCOMMITTED;    /* Enable uncommitted reads */
149
150    ret = dbp-&gt;open(dbp,        /* Pointer to the database */
151                    NULL,       /* Txn pointer */
152                    file_name,  /* File name */
153                    NULL,       /* Logical db name */
154                    DB_BTREE,   /* Database type (using btree) */
155                    db_flags,   /* Open flags */
156                    0);         /* File mode. Using defaults */
157    if (ret != 0) {
158        envp-&gt;err(envp, ret, "Database '%s' open failed",
159            file_name);
160        goto err;
161    }
162
163    /* Get the txn handle */
164    /* Note that this is a degree 3 transaction */
165    ret = envp-&gt;txn_begin(envp, NULL, &amp;txn, 0);
166    if (ret != 0) {
167        envp-&gt;err(envp, ret, "Transaction begin failed.");
168        goto err;
169    }
170
171    /* Get the cursor, supply the txn handle at that time */
172    /* Cause the cursor to perform uncommitted reads */
173    ret = dbp-&gt;cursor(dbp, txn, &amp;cursorp, DB_READ_UNCOMMITTED);
174    if (ret != 0) {
175        envp-&gt;err(envp, ret, "Cursor open failed.");
176        txn-&gt;abort(txn);
177        goto err;
178    }
179
180    /*
181     * From here, you perform your cursor reads and writes as normal,
182     * committing and aborting the transactions as is necessary, and 
183     * testing for deadlock exceptions as normal (omitted for brevity). 
184     */
185
186     ...  </pre>
187      </div>
188    </div>
189    <div class="navfooter">
190      <hr />
191      <table width="100%" summary="Navigation footer">
192        <tr>
193          <td width="40%" align="left"><a accesskey="p" href="isolation.html">Prev</a>��</td>
194          <td width="20%" align="center">
195            <a accesskey="u" href="txnconcurrency.html">Up</a>
196          </td>
197          <td width="40%" align="right">��<a accesskey="n" href="readmodifywrite.html">Next</a></td>
198        </tr>
199        <tr>
200          <td width="40%" align="left" valign="top">Isolation��</td>
201          <td width="20%" align="center">
202            <a accesskey="h" href="index.html">Home</a>
203          </td>
204          <td width="40%" align="right" valign="top">��Read/Modify/Write</td>
205        </tr>
206      </table>
207    </div>
208  </body>
209</html>
210