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. <span>This is true of both 49 base API and DPL cursors.</span> 50 </p> 51 <p> 52 Also, remember that when you are using the default isolation level, 53 every time your cursor reads a record it locks 54 that record until the encompassing transaction is resolved. This 55 means that walking your database with a transactional cursor 56 increases the chance of lock contention. 57 </p> 58 <p> 59 For this reason, if you must routinely walk your database with a 60 transactional cursor, consider using a reduced isolation level 61 such as read committed. <span>This is 62 true of both base API and DPL cursors.</span> 63 </p> 64 <div class="sect2" lang="en" xml:lang="en"> 65 <div class="titlepage"> 66 <div> 67 <div> 68 <h3 class="title"><a id="cursordirtyreads"></a>Using Cursors with Uncommitted Data</h3> 69 </div> 70 </div> 71 </div> 72 <p> 73 74 As described in <a class="xref" href="isolation.html#dirtyreads" title="Reading Uncommitted Data">Reading Uncommitted Data</a> 75 above, it is possible to relax your transaction's isolation 76 level such that it can read data modified but not yet committed 77 by another transaction. You can configure this when you create 78 your transaction handle, and when you do so then all cursors opened 79 inside that transaction will automatically use uncommitted reads. 80 </p> 81 <p> 82 You can also do this when you create a cursor handle from within 83 a serializable transaction. When you do this, only those 84 cursors configured for uncommitted reads uses uncommitted reads. 85 </p> 86 <p> 87 Either way, you must first configure your database 88 <span>or store</span> handle to support 89 uncommitted reads before you can configure your transactions or 90 your cursors to use them. 91 </p> 92 <p> 93 The following example shows how to configure an individual cursor handle 94 to read uncommitted data from within a serializable (full isolation) transaction. 95 For an example of 96 configuring a transaction to perform uncommitted reads in 97 general, see <a class="xref" href="isolation.html#dirtyreads" title="Reading Uncommitted Data">Reading Uncommitted Data</a>. 98 </p> 99 <pre class="programlisting">package db.txn; 100 101import com.sleepycat.db.Cursor; 102import com.sleepycat.db.CursorConfig; 103import com.sleepycat.db.Database; 104import com.sleepycat.db.DatabaseConfig; 105import com.sleepycat.db.Environment; 106import com.sleepycat.db.EnvironmentConfig; 107 108import java.io.File; 109 110... 111 112Database myDatabase = null; 113Environment myEnv = null; 114try { 115 116 EnvironmentConfig myEnvConfig = new EnvironmentConfig(); 117 myEnvConfig.setTransactional(true); 118 myEnvConfig.setInitializeCache(true); 119 myEnvConfig.setInitializeLocking(true); 120 myEnvConfig.setInitializeLogging(true); 121 122 myEnv = new Environment(new File("/my/env/home"), 123 myEnvConfig); 124 125 // Open the database. 126 DatabaseConfig dbConfig = new DatabaseConfig(); 127 dbConfig.setTransactional(true); 128 dbConfig.setType(DatabaseType.BTREE); 129 dbConfig.setReadUncommitted(true); // Enable uncommitted reads. 130 myDatabase = myEnv.openDatabase(null, // txn handle 131 "sampleDatabase", // db file name 132 null, // db name 133 dbConfig); 134 135 // Open the transaction. Note that this is a degree 3 136 // transaction. 137 Transaction txn = myEnv.beginTransaction(null, null); 138 Cursor cursor = null; 139 try { 140 // Use the transaction handle here 141 // Get our cursor. Note that we pass the transaction 142 // handle here. Note also that we cause the cursor 143 // to perform uncommitted reads. 144 CursorConfig cconfig = new CursorConfig(); 145 cconfig.setReadUncommitted(true); 146 cursor = db.openCursor(txn, cconfig); 147 148 // From here, you perform your cursor reads and writes 149 // as normal, committing and aborting the transactions as 150 // is necessary, and testing for deadlock exceptions as 151 // normal (omitted for brevity). 152 153 ... </pre> 154 <p> 155 If you are using the DPL: 156</p> 157 <pre class="programlisting">package persist.txn; 158 159import com.sleepycat.db.CursorConfig; 160import com.sleepycat.db.DatabaseConfig; 161import com.sleepycat.db.Environment; 162import com.sleepycat.db.EnvironmentConfig; 163 164import com.sleepycat.persist.EntityCursor; 165import com.sleepycat.persist.EntityStore; 166import com.sleepycat.persist.PrimaryIndex; 167import com.sleepycat.persist.StoreConfig; 168 169import java.util.Iterator; 170 171import java.io.File; 172 173... 174 175EntityStore myStore = null; 176Environment myEnv = null; 177PrimaryIndex<String,AnEntityClass> pKey; 178 179try { 180 181 EnvironmentConfig myEnvConfig = new EnvironmentConfig(); 182 myEnvConfig.setTransactional(true); 183 myEnvConfig.setInitializeCache(true); 184 myEnvConfig.setInitializeLocking(true); 185 myEnvConfig.setInitializeLogging(true); 186 187 myEnv = new Environment(new File("/my/env/home"), 188 myEnvConfig); 189 190 // Set up the entity store 191 StoreConfig myStoreConfig = new StoreConfig(); 192 myStoreConfig.setAllowCreate(true); 193 myStoreConfig.setTransactional(true); 194 195 // Configure uncommitted reads 196 DatabaseConfig dbConfig = new DatabaseConfig(); 197 dbConfig.setTransactional(true); 198 dbConfig.setType(DatabaseType.BTREE); 199 dbConfig.setAllowCreate(true); 200 dbConfig.setReadUncommitted(true); // Enable uncommitted reads. 201 202 // Instantiate the store 203 myStore = new EntityStore(myEnv, storeName, myStoreConfig); 204 205 // Set the DatabaseConfig object, so that the underlying 206 // database is configured for uncommitted reads. 207 myStore.setPrimaryConfig(AnEntityClass.class, myDbConfig); 208 209 // Open the transaction. Note that this is a degree 3 210 // transaction. 211 Transaction txn = myEnv.beginTransaction(null, null); 212 213 //Configure our cursor for uncommitted reads. 214 CursorConfig cconfig = new CursorConfig(); 215 cconfig.setReadUncommitted(true); 216 217 // Get our cursor. Note that we pass the transaction 218 // handle here. Note also that we cause the cursor 219 // to perform uncommitted reads. 220 EntityCursor<AnEntityClass> cursor = pKey.entities(txn, cconfig); 221 222 try { 223 // From here, you perform your cursor reads and writes 224 // as normal, committing and aborting the transactions as 225 // is necessary, and testing for deadlock exceptions as 226 // normal (omitted for brevity). 227 228 ... </pre> 229 </div> 230 </div> 231 <div class="navfooter"> 232 <hr /> 233 <table width="100%" summary="Navigation footer"> 234 <tr> 235 <td width="40%" align="left"><a accesskey="p" href="isolation.html">Prev</a> </td> 236 <td width="20%" align="center"> 237 <a accesskey="u" href="txnconcurrency.html">Up</a> 238 </td> 239 <td width="40%" align="right"> <a accesskey="n" href="readmodifywrite.html">Next</a></td> 240 </tr> 241 <tr> 242 <td width="40%" align="left" valign="top">Isolation </td> 243 <td width="20%" align="center"> 244 <a accesskey="h" href="index.html">Home</a> 245 </td> 246 <td width="40%" align="right" valign="top"> Read/Modify/Write</td> 247 </tr> 248 </table> 249 </div> 250 </body> 251</html> 252