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>Chapter 3. Transaction Basics</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="index.html" title="Getting Started with Berkeley DB Transaction Processing" /> 11 <link rel="prev" href="envopen.html" title="Opening a Transactional Environment and Database" /> 12 <link rel="next" href="abortresults.html" title="Aborting a Transaction" /> 13 </head> 14 <body> 15 <div class="navheader"> 16 <table width="100%" summary="Navigation header"> 17 <tr> 18 <th colspan="3" align="center">Chapter 3. Transaction Basics</th> 19 </tr> 20 <tr> 21 <td width="20%" align="left"><a accesskey="p" href="envopen.html">Prev</a> </td> 22 <th width="60%" align="center"> </th> 23 <td width="20%" align="right"> <a accesskey="n" href="abortresults.html">Next</a></td> 24 </tr> 25 </table> 26 <hr /> 27 </div> 28 <div class="chapter" lang="en" xml:lang="en"> 29 <div class="titlepage"> 30 <div> 31 <div> 32 <h2 class="title"><a id="usingtxns"></a>Chapter 3. Transaction Basics</h2> 33 </div> 34 </div> 35 </div> 36 <div class="toc"> 37 <p> 38 <b>Table of Contents</b> 39 </p> 40 <dl> 41 <dt> 42 <span class="sect1"> 43 <a href="usingtxns.html#commitresults">Committing a Transaction</a> 44 </span> 45 </dt> 46 <dd> 47 <dl> 48 <dt> 49 <span class="sect2"> 50 <a href="usingtxns.html#nodurabletxn">Non-Durable Transactions</a> 51 </span> 52 </dt> 53 </dl> 54 </dd> 55 <dt> 56 <span class="sect1"> 57 <a href="abortresults.html">Aborting a Transaction</a> 58 </span> 59 </dt> 60 <dt> 61 <span class="sect1"> 62 <a href="autocommit.html">Auto Commit</a> 63 </span> 64 </dt> 65 <dt> 66 <span class="sect1"> 67 <a href="nestedtxn.html">Nested Transactions</a> 68 </span> 69 </dt> 70 <dt> 71 <span class="sect1"> 72 <a href="txncursor.html">Transactional Cursors</a> 73 </span> 74 </dt> 75 <dt> 76 <span class="sect1"> 77 <a href="txnindices.html">Secondary Indices with Transaction Applications</a> 78 </span> 79 </dt> 80 <dt> 81 <span class="sect1"> 82 <a href="maxtxns.html">Configuring the Transaction Subsystem</a> 83 </span> 84 </dt> 85 </dl> 86 </div> 87 <p> 88 Once you have enabled transactions for your environment and your databases, 89 you can use them to protect your database operations. You do this by 90 acquiring a transaction handle and then using that handle for any 91 database operation that you want to participate in that transaction. 92 </p> 93 <p> 94 You obtain a transaction handle using the 95 96 <span><code class="methodname">DbEnv::txn_begin()</code> method.</span> 97 98 99 100 </p> 101 <p> 102 Once you have completed all of the operations that you want to include 103 in the transaction, you must commit the transaction using the 104 105 <span><code class="methodname">DbTxn::commit()</code> method.</span> 106 107 108 109 110 </p> 111 <p> 112 If, for any reason, you want to abandon the transaction, you abort 113 it using 114 115 <span><code class="methodname">DbTxn::abort()</code>.</span> 116 117 118 119 120 121 </p> 122 <p> 123 Any transaction handle that has been committed or aborted can no longer 124 be used by your application. 125 </p> 126 <p> 127 Finally, you must make sure that all transaction handles are either 128 committed or aborted before closing your databases and environment. 129 </p> 130 <div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"> 131 <h3 class="title">Note</h3> 132 <p> 133 If you only want to transaction protect a single database write operation, you can use auto commit to 134 perform the transaction administration. When you use auto commit, you do not need an explicit transaction 135 handle. See <a class="xref" href="autocommit.html" title="Auto Commit">Auto Commit</a> for more information. 136 </p> 137 </div> 138 <p> 139 For example, the following example opens a transactional-enabled environment and 140 database, obtains a transaction handle, and then performs a write 141 operation under its protection. In the event of any failure in the 142 write operation, the transaction is aborted and the database is left in a 143 state as if no operations had ever been attempted in the first place. 144 </p> 145 <pre class="programlisting">#include "db_cxx.h" 146 147... 148 149int main(void) 150{ 151 u_int32_t env_flags = DB_CREATE | // If the environment does not 152 // exist, create it. 153 DB_INIT_LOCK | // Initialize locking 154 DB_INIT_LOG | // Initialize logging 155 DB_INIT_MPOOL | // Initialize the cache 156 DB_INIT_TXN; // Initialize transactions 157 158 u_int32_t db_flags = DB_CREATE | DB_AUTO_COMMIT; 159 Db *dbp = NULL; 160 const char *file_name = "mydb.db"; 161 const char *keystr ="thekey"; 162 const char *datastr = "thedata"; 163 164 std::string envHome("/export1/testEnv"); 165 DbEnv myEnv(0); 166 167 try { 168 169 myEnv.open(envHome.c_str(), env_flags, 0); 170 dbp = new Db(&myEnv, 0); 171 172 // Open the database. Note that we are using auto commit for 173 // the open, so the database is able to support transactions. 174 dbp->open(NULL, // Txn pointer 175 file_name, // File name 176 NULL, // Logical db name 177 DB_BTREE, // Database type (using btree) 178 db_flags, // Open flags 179 0); // File mode. Using defaults 180 181 Dbt key, data; 182 key.set_data(keystr); 183 key.set_size((strlen(keystr) + 1) * sizeof(char)); 184 key.set_data(datastr); 185 key.set_size((strlen(datastr) + 1) * sizeof(char)); 186 187 DbTxn *txn = NULL; 188 myEnv.txn_begin(NULL, &txn, 0); 189 try { 190 db->put(txn, &key, &data, 0); 191 txn->commit(0); 192 } catch (DbException &e) { 193 std::cerr << "Error in transaction: " 194 << e.what() << std::endl; 195 txn->abort(); 196 } 197 198 } catch(DbException &e) { 199 std::cerr << "Error opening database and environment: " 200 << file_name << ", " 201 << envHome << std::endl; 202 std::cerr << e.what() << std::endl; 203 } 204 205 try { 206 if (dbp != NULL) 207 dbp->close(0); 208 myEnv.close(0); 209 } catch(DbException &e) { 210 std::cerr << "Error closing database and environment: " 211 << file_name << ", " 212 << envHome << std::endl; 213 std::cerr << e.what() << std::endl; 214 return (EXIT_FAILURE); 215 } 216 217 return (EXIT_SUCCESS); 218} </pre> 219 <div class="sect1" lang="en" xml:lang="en"> 220 <div class="titlepage"> 221 <div> 222 <div> 223 <h2 class="title" style="clear: both"><a id="commitresults"></a>Committing a Transaction</h2> 224 </div> 225 </div> 226 </div> 227 <div class="toc"> 228 <dl> 229 <dt> 230 <span class="sect2"> 231 <a href="usingtxns.html#nodurabletxn">Non-Durable Transactions</a> 232 </span> 233 </dt> 234 </dl> 235 </div> 236 <p> 237 In order to fully understand what is happening when you commit 238 a transaction, you must first understand a little about what 239 DB is doing with 240 241 <span> 242 the logging subsystem. 243 </span> 244 245 246 247 Logging causes all database write operations to be identified in 248 249 <span>logs, and by default these 250 logs are backed by files on disk. These logs are used to restore your databases 251 252 </span> 253 254 255 256 in the event of a system or application failure, so by performing 257 logging, DB ensures the integrity of your data. 258 </p> 259 <p> 260 Moreover, DB performs <span class="emphasis"><em>write-ahead</em></span> 261 logging. This means that information is written to the logs 262 <span class="emphasis"><em>before</em></span> the actual database 263 264 is changed. 265 This means that all write activity performed under the 266 protection of the transaction is noted in the log before 267 the transaction is committed. Be aware, however, that database 268 maintains logs in-memory. If you are backing your logs on 269 disk, the log information will eventually be written to the log 270 files, but while the transaction is on-going the log data may be 271 held only in memory. 272 </p> 273 <p> 274 When you commit a transaction, the following occurs: 275 </p> 276 <div class="itemizedlist"> 277 <ul type="disc"> 278 <li> 279 <p> 280 A commit record is written to the log. This 281 indicates that the modifications made by the 282 transaction are now permanent. By default, this write is performed synchronously to disk so the 283 commit record arrives in the log files before any other actions are taken. 284 </p> 285 </li> 286 <li> 287 <p> 288 Any log information held in memory is (by default) 289 synchronously written to disk. Note that this requirement can be 290 relaxed, depending on the type of commit you perform. 291 See <a class="xref" href="usingtxns.html#nodurabletxn" title="Non-Durable Transactions">Non-Durable Transactions</a> for 292 more information. 293 <span>Also, if you are 294 maintaining your logs entirely in-memory, then this 295 step will of course not be taken. To configure your 296 logging system for in-memory usage, see 297 <a class="xref" href="logconfig.html#inmemorylogging" title="Configuring In-Memory Logging">Configuring In-Memory Logging</a>. 298 </span> 299 </p> 300 </li> 301 <li> 302 <p> 303 All locks held by the transaction are released. This means 304 that read operations performed by other transactions or 305 threads of control can now see the modifications without 306 resorting to uncommitted reads (see <a class="xref" href="isolation.html#dirtyreads" title="Reading Uncommitted Data">Reading Uncommitted Data</a> for more information). 307 </p> 308 </li> 309 </ul> 310 </div> 311 <p> 312 To commit a transaction, you simply call 313 314 <span><code class="methodname">DbTxn::commit()</code>.</span> 315 316 317 318 </p> 319 <p> 320 Notice that committing a transaction does not necessarily cause data 321 modified in your memory cache to be written to the files 322 backing your databases on disk. Dirtied database pages are written 323 for a number of reasons, but a transactional 324 commit is not one of them. The following are the things that can cause a dirtied 325 database page to be written to the backing database file: 326 </p> 327 <div class="itemizedlist"> 328 <ul type="disc"> 329 <li> 330 <p> 331 Checkpoints. 332 </p> 333 <p> 334 Checkpoints cause all dirtied pages currently existing 335 in the cache to be written to disk, and a checkpoint 336 record is then written to the logs. You can run checkpoints 337 explicitly. For more information on checkpoints, 338 see <a class="xref" href="filemanagement.html#checkpoints" title="Checkpoints">Checkpoints</a>. 339 </p> 340 </li> 341 <li> 342 <p> 343 Cache is full. 344 </p> 345 <p> 346 If the in-memory cache fills up, then dirtied pages 347 might be written to disk in order to free up space for other 348 pages that your application needs to use. Note that if 349 dirtied pages are written to the database files, then 350 any log records that describe how those pages were 351 dirtied are written to disk before the database 352 pages are written. 353 </p> 354 </li> 355 </ul> 356 </div> 357 <p> 358 Be aware that because your transaction commit caused database 359 360 modifications recorded in your logs to be forced to disk, your modifications 361 are by default "persistent" in that they can be recovered in the event of 362 an application or system failure. However, recovery time is 363 gated by how much data has been modified since the last 364 checkpoint, so for applications that perform a lot of writes, 365 you may want to run a checkpoint with some frequency. 366 </p> 367 <p> 368 Note that once you have committed a transaction, the transaction 369 handle that you used for the transaction is no longer valid. To 370 perform database activities under the control of a new 371 transaction, you must obtain a fresh transaction handle. 372 </p> 373 <div class="sect2" lang="en" xml:lang="en"> 374 <div class="titlepage"> 375 <div> 376 <div> 377 <h3 class="title"><a id="nodurabletxn"></a>Non-Durable Transactions</h3> 378 </div> 379 </div> 380 </div> 381 <p> 382 As previously noted, by default transaction commits are 383 durable because they cause the modifications performed 384 under the transaction to be synchronously recorded in 385 your on-disk log files. However, it is possible to use 386 non-durable transactions. 387 </p> 388 <p> 389 You may want non-durable transactions for performance 390 reasons. For example, you might be using transactions 391 simply for the isolation guarantee. 392 393 <span> 394 In this case, you might 395 not want a durability guarantee and so you may want to 396 prevent the disk I/O that normally accompanies a 397 transaction commit. 398 </span> 399 400 </p> 401 <p> 402 There are several ways to remove the durability guarantee 403 for your transactions: 404 </p> 405 <div class="itemizedlist"> 406 <ul type="disc"> 407 <li> 408 <p> 409 Specify 410 <span> 411 <code class="literal">DB_TXN_NOSYNC</code> using the 412 413 <code class="methodname">DbEnv::set_flags()</code> 414 method. 415 </span> 416 417 This causes DB to not synchronously force any 418 <span> 419 log 420 </span> 421 data to disk upon transaction commit. 422 423 <span> 424 That is, the modifications are held entirely 425 in the in-memory cache and the logging 426 information is not forced to the filesystem for 427 long-term storage. 428 </span> 429 430 Note, however, that the 431 <span> 432 logging 433 </span> 434 data will eventually make it to the filesystem (assuming no 435 application or OS crashes) as a part of DB's 436 management of its logging buffers and/or cache. 437 </p> 438 <p> 439 This form of a commit provides a weak durability 440 guarantee because data loss can occur due to 441 an application 442 or OS crash. 443 </p> 444 <p> 445 This behavior is specified on a per-environment 446 handle basis. In order for your application to exhibit consistent 447 behavior, you need to specify this 448 <span>flag</span> 449 450 for all of the environment handles used in your application. 451 </p> 452 <p> 453 You can achieve this behavior on a transaction by transaction basis by 454 <span> 455 specifying <code class="literal">DB_TXN_NOSYNC</code> to the 456 457 <code class="methodname">DbTxn::commit()</code> 458 459 method. 460 </span> 461 462 463 464 </p> 465 </li> 466 <li> 467 <p> 468 Specify 469 <span> 470 <code class="literal">DB_TXN_WRITE_NOSYNC</code> using the 471 472 <code class="methodname">DbEnv::set_flags()</code> 473 method. 474 </span> 475 476 477 478 This causes 479 <span> 480 logging 481 </span> 482 data to be synchronously 483 written to the OS's file system buffers upon 484 transaction commit. The data will eventually be 485 written to disk, but this occurs when the 486 operating system chooses to schedule the 487 activity; the transaction commit can complete 488 successfully before this disk I/O is performed 489 by the OS. 490 </p> 491 <p> 492 This form of commit protects you against application 493 crashes, but not against OS 494 crashes. This method offers less room for the possibility of data loss than does 495 <span><code class="literal">DB_TXN_NOSYNC</code>.</span> 496 497 </p> 498 <p> 499 This behavior is specified on a per-environment 500 handle basis. In order for your application to exhibit consistent 501 behavior, you need to specify this 502 <span>flag</span> 503 504 for all of the environment handles used in your application. 505 </p> 506 </li> 507 <li> 508 <p> 509 Maintain your logs entirely in-memory. In this 510 case, your logs are never written to disk. The 511 result is that you lose all durability guarantees. 512 See 513 <a class="xref" href="logconfig.html#inmemorylogging" title="Configuring In-Memory Logging">Configuring In-Memory Logging</a> 514 for more information. 515 </p> 516 </li> 517 </ul> 518 </div> 519 </div> 520 </div> 521 </div> 522 <div class="navfooter"> 523 <hr /> 524 <table width="100%" summary="Navigation footer"> 525 <tr> 526 <td width="40%" align="left"><a accesskey="p" href="envopen.html">Prev</a> </td> 527 <td width="20%" align="center"> </td> 528 <td width="40%" align="right"> <a accesskey="n" href="abortresults.html">Next</a></td> 529 </tr> 530 <tr> 531 <td width="40%" align="left" valign="top">Opening a Transactional Environment and 532 <span>Database</span> 533 534 535 </td> 536 <td width="20%" align="center"> 537 <a accesskey="h" href="index.html">Home</a> 538 </td> 539 <td width="40%" align="right" valign="top"> Aborting a Transaction</td> 540 </tr> 541 </table> 542 </div> 543 </body> 544</html> 545