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