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</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="Berkeley DB Programmer's Reference Guide" /> 10 <link rel="up" href="transapp.html" title="Chapter��11.�� Berkeley DB Transactional Data Store Applications" /> 11 <link rel="prev" href="transapp_read.html" title="Degrees of isolation" /> 12 <link rel="next" href="transapp_nested.html" title="Nested transactions" /> 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</th> 19 </tr> 20 <tr> 21 <td width="20%" align="left"><a accesskey="p" href="transapp_read.html">Prev</a>��</td> 22 <th width="60%" align="center">Chapter��11.�� 23 Berkeley DB Transactional Data Store Applications 24 </th> 25 <td width="20%" align="right">��<a accesskey="n" href="transapp_nested.html">Next</a></td> 26 </tr> 27 </table> 28 <hr /> 29 </div> 30 <div class="sect1" lang="en" xml:lang="en"> 31 <div class="titlepage"> 32 <div> 33 <div> 34 <h2 class="title" style="clear: both"><a id="transapp_cursor"></a>Transactional cursors</h2> 35 </div> 36 </div> 37 </div> 38 <p>Berkeley DB cursors may be used inside a transaction, exactly as any other 39<a href="../api_reference/C/db.html" class="olink">DB</a> method. The enclosing transaction ID must be specified when 40the cursor is created, but it does not then need to be further specified 41on operations performed using the cursor. One important point to 42remember is that a cursor <span class="bold"><strong>must be closed</strong></span> before the enclosing 43transaction is committed or aborted.</p> 44 <p>The following code fragment uses a cursor to store a new key in the cats 45database with four associated data items. The key is a name. The data 46items are a company name and a list of the breeds of cat owned. Each 47of the data entries is stored as a duplicate data item. In this 48example, transactions are necessary to ensure that either all or none 49of the data items appear in case of system or application failure.</p> 50 <pre class="programlisting">int 51main(int argc, char *argv) 52{ 53 extern int optind; 54 DB *db_cats, *db_color, *db_fruit; 55 DB_ENV *dbenv; 56 int ch; 57 58 while ((ch = getopt(argc, argv, "")) != EOF) 59 switch (ch) { 60 case '?': 61 default: 62 usage(); 63 } 64 argc -= optind; 65 argv += optind; 66 67 env_dir_create(); 68 env_open(&dbenv); 69 70 /* Open database: Key is fruit class; Data is specific type. */ 71 db_open(dbenv, &db_fruit, "fruit", 0); 72 73 /* Open database: Key is a color; Data is an integer. */ 74 db_open(dbenv, &db_color, "color", 0); 75 76 /* 77 * Open database: 78 * Key is a name; Data is: company name, cat breeds. 79 */ 80 db_open(dbenv, &db_cats, "cats", 1); 81 82 add_fruit(dbenv, db_fruit, "apple", "yellow delicious"); 83 84 add_color(dbenv, db_color, "blue", 0); 85 add_color(dbenv, db_color, "blue", 3); 86 87<span class="bold"><strong> add_cat(dbenv, db_cats, 88 "Amy Adams", 89 "Oracle", 90 "abyssinian", 91 "bengal", 92 "chartreaux", 93 NULL);</strong></span> 94 95 return (0); 96} 97 98<span class="bold"><strong>int 99add_cat(DB_ENV *dbenv, DB *db, char *name, ...) 100{ 101 va_list ap; 102 DBC *dbc; 103 DBT key, data; 104 DB_TXN *tid; 105 int fail, ret, t_ret; 106 char *s; 107 108 /* Initialization. */ 109 fail = 0; 110 111 memset(&key, 0, sizeof(key)); 112 memset(&data, 0, sizeof(data)); 113 key.data = name; 114 key.size = strlen(name); 115 116retry: /* Begin the transaction. */ 117 if ((ret = dbenv->txn_begin(dbenv, NULL, &tid, 0)) != 0) { 118 dbenv->err(dbenv, ret, "DB_ENV->txn_begin"); 119 exit (1); 120 } 121 122 /* Delete any previously existing item. */ 123 switch (ret = db->del(db, tid, &key, 0)) { 124 case 0: 125 case DB_NOTFOUND: 126 break; 127 case DB_LOCK_DEADLOCK: 128 default: 129 /* Retry the operation. */ 130 if ((t_ret = tid->abort(tid)) != 0) { 131 dbenv->err(dbenv, t_ret, "DB_TXN->abort"); 132 exit (1); 133 } 134 if (fail++ == MAXIMUM_RETRY) 135 return (ret); 136 goto retry; 137 } 138 139 /* Create a cursor. */ 140 if ((ret = db->cursor(db, tid, &dbc, 0)) != 0) { 141 dbenv->err(dbenv, ret, "db->cursor"); 142 exit (1); 143 } 144 145 /* Append the items, in order. */ 146 va_start(ap, name); 147 while ((s = va_arg(ap, char *)) != NULL) { 148 data.data = s; 149 data.size = strlen(s); 150 switch (ret = dbc->c_put(dbc, &key, &data, DB_KEYLAST)) { 151 case 0: 152 break; 153 case DB_LOCK_DEADLOCK: 154 default: 155 va_end(ap); 156 157 /* Retry the operation. */ 158 if ((t_ret = dbc->c_close(dbc)) != 0) { 159 dbenv->err( 160 dbenv, t_ret, "dbc->c_close"); 161 exit (1); 162 } 163 if ((t_ret = tid->abort(tid)) != 0) { 164 dbenv->err(dbenv, t_ret, "DB_TXN->abort"); 165 exit (1); 166 } 167 if (fail++ == MAXIMUM_RETRY) 168 return (ret); 169 goto retry; 170 } 171 } 172 va_end(ap); 173 174 /* Success: commit the change. */ 175 if ((ret = dbc->c_close(dbc)) != 0) { 176 dbenv->err(dbenv, ret, "dbc->c_close"); 177 exit (1); 178 } 179 if ((ret = tid->commit(tid, 0)) != 0) { 180 dbenv->err(dbenv, ret, "DB_TXN->commit"); 181 exit (1); 182 } 183 return (0); 184}</strong></span></pre> 185 </div> 186 <div class="navfooter"> 187 <hr /> 188 <table width="100%" summary="Navigation footer"> 189 <tr> 190 <td width="40%" align="left"><a accesskey="p" href="transapp_read.html">Prev</a>��</td> 191 <td width="20%" align="center"> 192 <a accesskey="u" href="transapp.html">Up</a> 193 </td> 194 <td width="40%" align="right">��<a accesskey="n" href="transapp_nested.html">Next</a></td> 195 </tr> 196 <tr> 197 <td width="40%" align="left" valign="top">Degrees of isolation��</td> 198 <td width="20%" align="center"> 199 <a accesskey="h" href="index.html">Home</a> 200 </td> 201 <td width="40%" align="right" valign="top">��Nested transactions</td> 202 </tr> 203 </table> 204 </div> 205 </body> 206</html> 207