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 <stdio.h> 98#include <stdlib.h> 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(&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->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(&dbp, envp, 0); 140 if (ret != 0) { 141 envp->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->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->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->txn_begin(envp, NULL, &txn, 0); 166 if (ret != 0) { 167 envp->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->cursor(dbp, txn, &cursorp, DB_READ_UNCOMMITTED); 174 if (ret != 0) { 175 envp->err(envp, ret, "Cursor open failed."); 176 txn->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