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