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.62.4" /> 9 <link rel="home" 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="previous" 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></div> 36 </div> 37 <p> 38 When you use transactional cursors with a concurrent application, remember that 39 in the event of a deadlock you must make sure that you close your cursor before you abort and retry your 40 transaction. 41 </p> 42 <p> 43 Also, remember that when you are using the default isolation level, 44 every time your cursor reads a record it locks 45 that record until the encompassing transaction is resolved. This 46 means that walking your database with a transactional cursor 47 increases the chance of lock contention. 48 </p> 49 <p> 50 For this reason, if you must routinely walk your database with a 51 transactional cursor, consider using a reduced isolation level 52 such as read committed. 53 </p> 54 <div class="sect2" lang="en" xml:lang="en"> 55 <div class="titlepage"> 56 <div> 57 <div> 58 <h3 class="title"><a id="cursordirtyreads"></a>Using Cursors with Uncommitted Data</h3> 59 </div> 60 </div> 61 <div></div> 62 </div> 63 <p> 64 65 As described in <a href="isolation.html#dirtyreads">Reading Uncommitted Data</a> 66 above, it is possible to relax your transaction's isolation 67 level such that it can read data modified but not yet committed 68 by another transaction. You can configure this when you create 69 your transaction handle, and when you do so then all cursors opened 70 inside that transaction will automatically use uncommitted reads. 71 </p> 72 <p> 73 You can also do this when you create a cursor handle from within 74 a serializable transaction. When you do this, only those 75 cursors configured for uncommitted reads uses uncommitted reads. 76 </p> 77 <p> 78 Either way, you must first configure your database 79 handle to support 80 uncommitted reads before you can configure your transactions or 81 your cursors to use them. 82 </p> 83 <p> 84 The following example shows how to configure an individual cursor handle 85 to read uncommitted data from within a serializable (full isolation) transaction. 86 For an example of 87 configuring a transaction to perform uncommitted reads in 88 general, see <a href="isolation.html#dirtyreads">Reading Uncommitted Data</a>. 89 </p> 90 <pre class="programlisting">#include <stdio.h> 91#include <stdlib.h> 92 93#include "db.h" 94 95int 96main(void) 97{ 98 DB *dbp; 99 DBC *cursorp; 100 DB_ENV *envp; 101 DB_TXN *txn; 102 int ret, c_ret; 103 char *replacementString = "new string"; 104 105 dbp = NULL; 106 envp = NULL; 107 txn = NULL; 108 109 /* Open the environment */ 110 ret = db_env_create(&envp, 0); 111 if (ret != 0) { 112 fprintf(stderr, "Error creating environment handle: %s\n", 113 db_strerror(ret)); 114 return (EXIT_FAILURE); 115 } 116 117 env_flags = DB_CREATE | /* Create the environment if it does 118 * not already exist. */ 119 DB_INIT_TXN | /* Initialize transactions */ 120 DB_INIT_LOCK | /* Initialize locking. */ 121 DB_INIT_LOG | /* Initialize logging */ 122 DB_INIT_MPOOL; /* Initialize the in-memory cache. */ 123 124 ret = envp->open(envp, db_home_dir, env_flags, 0); 125 if (ret != 0) { 126 fprintf(stderr, "Error opening environment: %s\n", 127 db_strerror(ret)); 128 goto err; 129 } 130 131 /* Initialize the DB handle */ 132 ret = db_create(&dbp, envp, 0); 133 if (ret != 0) { 134 envp->err(envp, ret, "Database creation failed"); 135 goto err; 136 } 137 138 db_flags = DB_CREATE | /* Create the db if it does not 139 * exist */ 140 DB_AUTO_COMMIT | /* Enable auto commit */ 141 DB_READ_UNCOMMITTED; /* Enable uncommitted reads */ 142 143 ret = dbp->open(dbp, /* Pointer to the database */ 144 NULL, /* Txn pointer */ 145 file_name, /* File name */ 146 NULL, /* Logical db name */ 147 DB_BTREE, /* Database type (using btree) */ 148 db_flags, /* Open flags */ 149 0); /* File mode. Using defaults */ 150 if (ret != 0) { 151 envp->err(envp, ret, "Database '%s' open failed", 152 file_name); 153 goto err; 154 } 155 156 /* Get the txn handle */ 157 /* Note that this is a degree 3 transaction */ 158 ret = envp->txn_begin(envp, NULL, &txn, 0); 159 if (ret != 0) { 160 envp->err(envp, ret, "Transaction begin failed."); 161 goto err; 162 } 163 164 /* Get the cursor, supply the txn handle at that time */ 165 /* Cause the cursor to perform uncommitted reads */ 166 ret = dbp->cursor(dbp, txn, &cursorp, DB_READ_UNCOMMITTED); 167 if (ret != 0) { 168 envp->err(envp, ret, "Cursor open failed."); 169 txn->abort(txn); 170 goto err; 171 } 172 173 /* 174 * From here, you perform your cursor reads and writes as normal, 175 * committing and aborting the transactions as is necessary, and 176 * testing for deadlock exceptions as normal (omitted for brevity). 177 */ 178 179 ... </pre> 180 </div> 181 </div> 182 <div class="navfooter"> 183 <hr /> 184 <table width="100%" summary="Navigation footer"> 185 <tr> 186 <td width="40%" align="left"><a accesskey="p" href="isolation.html">Prev</a> </td> 187 <td width="20%" align="center"> 188 <a accesskey="u" href="txnconcurrency.html">Up</a> 189 </td> 190 <td width="40%" align="right"> <a accesskey="n" href="readmodifywrite.html">Next</a></td> 191 </tr> 192 <tr> 193 <td width="40%" align="left" valign="top">Isolation </td> 194 <td width="20%" align="center"> 195 <a accesskey="h" href="index.html">Home</a> 196 </td> 197 <td width="40%" align="right" valign="top"> Read/Modify/Write</td> 198 </tr> 199 </table> 200 </div> 201 </body> 202</html> 203