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 Store or 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 <dd> 77 <dl> 78 <dt> 79 <span class="sect2"> 80 <a href="txncursor.html#dplcursors">Using Transactional DPL Cursors</a> 81 </span> 82 </dt> 83 </dl> 84 </dd> 85 <dt> 86 <span class="sect1"> 87 <a href="txnindices.html">Secondary Indices with Transaction Applications</a> 88 </span> 89 </dt> 90 <dt> 91 <span class="sect1"> 92 <a href="maxtxns.html">Configuring the Transaction Subsystem</a> 93 </span> 94 </dt> 95 </dl> 96 </div> 97 <p> 98 Once you have enabled transactions for your environment and your databases, 99 you can use them to protect your database operations. You do this by 100 acquiring a transaction handle and then using that handle for any 101 database operation that you want to participate in that transaction. 102 </p> 103 <p> 104 You obtain a transaction handle using the 105 106 107 <span><tt class="methodname">Environment.beginTransaction()</tt> method.</span> 108 109 110 </p> 111 <p> 112 Once you have completed all of the operations that you want to include 113 in the transaction, you must commit the transaction using the 114 115 116 <span><tt class="methodname">Transaction.commit()</tt> method.</span> 117 118 119 120 </p> 121 <p> 122 If, for any reason, you want to abandon the transaction, you abort 123 it using 124 125 126 <span><tt class="methodname">Transaction.abort()</tt>.</span> 127 128 129 130 131 </p> 132 <p> 133 Any transaction handle that has been committed or aborted can no longer 134 be used by your application. 135 </p> 136 <p> 137 Finally, you must make sure that all transaction handles are either 138 committed or aborted before closing your databases and environment. 139 </p> 140 <div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"> 141 <h3 class="title">Note</h3> 142 <p> 143 If you only want to transaction protect a single database write operation, you can use auto commit to 144 perform the transaction administration. When you use auto commit, you do not need an explicit transaction 145 handle. See <a href="autocommit.html">Auto Commit</a> for more information. 146 </p> 147 </div> 148 <p> 149 For example, the following example opens a transactional-enabled environment and 150 store, obtains a transaction handle, and then performs a write 151 operation under its protection. In the event of any failure in the 152 write operation, the transaction is aborted and the store is left in a 153 state as if no operations had ever been attempted in the first place. 154 155 </p> 156 <pre class="programlisting">package persist.txn; 157 158import com.sleepycat.db.DatabaseException; 159import com.sleepycat.db.Environment; 160import com.sleepycat.db.EnvironmentConfig; 161import com.sleepycat.db.Transaction; 162 163import com.sleepycat.persist.EntityStore; 164import com.sleepycat.persist.StoreConfig; 165 166import java.io.File; 167import java.io.FileNotFoundException; 168 169... 170 171Environment myEnv = null; 172EntityStore store = null; 173 174// Our convenience data accessor class, used for easy access to 175// EntityClass indexes. 176DataAccessor da; 177 178try { 179 EnvironmentConfig myEnvConfig = new EnvironmentConfig(); 180 myEnvConfig.setInitializeCache(true); 181 myEnvConfig.setInitializeLocking(true); 182 myEnvConfig.setInitializeLogging(true); 183 myEnvConfig.setTransactional(true); 184 185 StoreConfig storeConfig = new StoreConfig(); 186 storeConfig.setTransactional(true); 187 188 myEnv = new Environment(new File("/my/env/home"), 189 myEnvConfig); 190 191 EntityStore store = new EntityStore(myEnv, 192 "EntityStore", storeConfig); 193 194 da = new DataAccessor(store); 195 196 // Assume that Inventory is an entity class. 197 Inventory theInventory = new Inventory(); 198 theInventory.setItemName("Waffles"); 199 theInventory.setItemSku("waf23rbni"); 200 201 Transaction txn = myEnv.beginTransaction(null, null); 202 203 try { 204 // Put the object to the store using the transaction handle. 205 da.inventoryBySku.put(txn, theInventory); 206 207 // Commit the transaction. The data is now safely written to the 208 // store. 209 txn.commit(); 210 // If there is a problem, abort the transaction 211 } catch (Exception e) { 212 if (txn != null) { 213 txn.abort(); 214 txn = null; 215 } 216 } 217 218 219} catch (DatabaseException de) { 220 // Exception handling goes here 221 } catch (FileNotFoundException fnfe) { 222 // Exception handling goes here 223}</pre> 224 <p> 225 The same thing can be done with the base API. In this case, the 226 database in use is left unchanged if the write operation fails: 227 </p> 228 <pre class="programlisting">package db.txn; 229 230import com.sleepycat.db.Database; 231import com.sleepycat.db.DatabaseConfig; 232import com.sleepycat.db.DatabaseEntry; 233import com.sleepycat.db.DatabaseException; 234import com.sleepycat.db.Environment; 235import com.sleepycat.db.EnvironmentConfig; 236import com.sleepycat.db.Transaction; 237 238import java.io.File; 239import java.io.FileNotFoundException; 240 241... 242 243Database myDatabase = null; 244Environment myEnv = null; 245try { 246 EnvironmentConfig myEnvConfig = new EnvironmentConfig(); 247 myEnvConfig.setInitializeCache(true); 248 myEnvConfig.setInitializeLocking(true); 249 myEnvConfig.setInitializeLogging(true); 250 myEnvConfig.setTransactional(true); 251 252 myEnv = new Environment(new File("/my/env/home"), 253 myEnvConfig); 254 255 // Open the database. 256 DatabaseConfig dbConfig = new DatabaseConfig(); 257 dbConfig.setTransactional(true); 258 dbConfig.setType(DatabaseType.BTREE); 259 myDatabase = myEnv.openDatabase(null, // txn handle 260 "sampleDatabase", // db file name 261 null, // db name 262 dbConfig); 263 String keyString = "thekey"; 264 String dataString = "thedata"; 265 DatabaseEntry key = 266 new DatabaseEntry(keyString.getBytes("UTF-8")); 267 DatabaseEntry data = 268 new DatabaseEntry(dataString.getBytes("UTF-8")); 269 270 Transaction txn = myEnv.beginTransaction(null, null); 271 272 try { 273 myDatabase.put(txn, key, data); 274 txn.commit(); 275 } catch (Exception e) { 276 if (txn != null) { 277 txn.abort(); 278 txn = null; 279 } 280 } 281 282} catch (DatabaseException de) { 283 // Exception handling goes here 284} catch (FileNotFoundException fnfe) { 285 // Exception handling goes here 286} </pre> 287 <div class="sect1" lang="en" xml:lang="en"> 288 <div class="titlepage"> 289 <div> 290 <div> 291 <h2 class="title" style="clear: both"><a id="commitresults"></a>Committing a Transaction</h2> 292 </div> 293 </div> 294 <div></div> 295 </div> 296 <p> 297 In order to fully understand what is happening when you commit 298 a transaction, you must first understand a little about what 299 DB is doing with 300 301 <span> 302 the logging subsystem. 303 </span> 304 305 306 307 Logging causes all database <span>or 308 store</span> write operations to be identified in 309 310 <span>logs, and by default these 311 logs are backed by files on disk. These logs are used to restore your databases 312 <span>or store</span> 313 </span> 314 315 316 317 in the event of a system or application failure, so by performing 318 logging, DB ensures the integrity of your data. 319 </p> 320 <p> 321 Moreover, DB performs <span class="emphasis"><em>write-ahead</em></span> 322 logging. This means that information is written to the logs 323 <span class="emphasis"><em>before</em></span> the actual database 324 <span> 325 or store 326 </span> 327 is changed. 328 This means that all write activity performed under the 329 protection of the transaction is noted in the log before 330 the transaction is committed. Be aware, however, that database 331 maintains logs in-memory. If you are backing your logs on 332 disk, the log information will eventually be written to the log 333 files, but while the transaction is on-going the log data may be 334 held only in memory. 335 </p> 336 <p> 337 When you commit a transaction, the following occurs: 338 </p> 339 <div class="itemizedlist"> 340 <ul type="disc"> 341 <li> 342 <p> 343 A commit record is written to the log. This 344 indicates that the modifications made by the 345 transaction are now permanent. By default, this write is performed synchronously to disk so the 346 commit record arrives in the log files before any other actions are taken. 347 </p> 348 </li> 349 <li> 350 <p> 351 Any log information held in memory is (by default) 352 synchronously written to disk. Note that this requirement can be 353 relaxed, depending on the type of commit you perform. 354 See <a href="usingtxns.html#nodurabletxn">Non-Durable Transactions</a> for 355 more information. 356 <span>Also, if you are 357 maintaining your logs entirely in-memory, then this 358 step will of course not be taken. To configure your 359 logging system for in-memory usage, see 360 <a href="logconfig.html#inmemorylogging">Configuring In-Memory Logging</a>. 361 </span> 362 </p> 363 </li> 364 <li> 365 <p> 366 All locks held by the transaction are released. This means 367 that read operations performed by other transactions or 368 threads of control can now see the modifications without 369 resorting to uncommitted reads (see <a href="isolation.html#dirtyreads">Reading Uncommitted Data</a> for more information). 370 </p> 371 </li> 372 </ul> 373 </div> 374 <p> 375 To commit a transaction, you simply call 376 377 378 <span><tt class="methodname">Transaction.commit()</tt>.</span> 379 380 381 </p> 382 <p> 383 Notice that committing a transaction does not necessarily cause data 384 modified in your memory cache to be written to the files 385 backing your databases on disk. Dirtied database pages are written 386 for a number of reasons, but a transactional 387 commit is not one of them. The following are the things that can cause a dirtied 388 database page to be written to the backing database file: 389 </p> 390 <div class="itemizedlist"> 391 <ul type="disc"> 392 <li> 393 <p> 394 Checkpoints. 395 </p> 396 <p> 397 Checkpoints cause all dirtied pages currently existing 398 in the cache to be written to disk, and a checkpoint 399 record is then written to the logs. You can run checkpoints 400 explicitly. For more information on checkpoints, 401 see <a href="filemanagement.html#checkpoints">Checkpoints</a>. 402 </p> 403 </li> 404 <li> 405 <p> 406 Cache is full. 407 </p> 408 <p> 409 If the in-memory cache fills up, then dirtied pages 410 might be written to disk in order to free up space for other 411 pages that your application needs to use. Note that if 412 dirtied pages are written to the database files, then 413 any log records that describe how those pages were 414 dirtied are written to disk before the database 415 pages are written. 416 </p> 417 </li> 418 </ul> 419 </div> 420 <p> 421 Be aware that because your transaction commit caused database 422 <span> 423 or store 424 </span> 425 modifications recorded in your logs to be forced to disk, your modifications 426 are by default "persistent" in that they can be recovered in the event of 427 an application or system failure. However, recovery time is 428 gated by how much data has been modified since the last 429 checkpoint, so for applications that perform a lot of writes, 430 you may want to run a checkpoint with some frequency. 431 </p> 432 <p> 433 Note that once you have committed a transaction, the transaction 434 handle that you used for the transaction is no longer valid. To 435 perform database activities under the control of a new 436 transaction, you must obtain a fresh transaction handle. 437 </p> 438 <div class="sect2" lang="en" xml:lang="en"> 439 <div class="titlepage"> 440 <div> 441 <div> 442 <h3 class="title"><a id="nodurabletxn"></a>Non-Durable Transactions</h3> 443 </div> 444 </div> 445 <div></div> 446 </div> 447 <p> 448 As previously noted, by default transaction commits are 449 durable because they cause the modifications performed 450 under the transaction to be synchronously recorded in 451 your on-disk log files. However, it is possible to use 452 non-durable transactions. 453 </p> 454 <p> 455 You may want non-durable transactions for performance 456 reasons. For example, you might be using transactions 457 simply for the isolation guarantee. 458 459 <span> 460 In this case, you might 461 not want a durability guarantee and so you may want to 462 prevent the disk I/O that normally accompanies a 463 transaction commit. 464 </span> 465 466 </p> 467 <p> 468 There are several ways to remove the durability guarantee 469 for your transactions: 470 </p> 471 <div class="itemizedlist"> 472 <ul type="disc"> 473 <li> 474 <p> 475 Specify 476 477 <span> 478 <tt class="literal">true</tt> to the 479 <tt class="methodname">EnvironmentConfig.setTxnNoSync()</tt> 480 481 method. 482 </span> 483 This causes DB to not synchronously force any 484 <span> 485 log 486 </span> 487 data to disk upon transaction commit. 488 489 <span> 490 That is, the modifications are held entirely 491 in the in-memory cache and the logging 492 information is not forced to the filesystem for 493 long-term storage. 494 </span> 495 496 Note, however, that the 497 <span> 498 logging 499 </span> 500 data will eventually make it to the filesystem (assuming no 501 application or OS crashes) as a part of DB's 502 management of its logging buffers and/or cache. 503 </p> 504 <p> 505 This form of a commit provides a weak durability 506 guarantee because data loss can occur due to 507 an application<span>, JVM,</span> 508 or OS crash. 509 </p> 510 <p> 511 This behavior is specified on a per-environment 512 handle basis. In order for your application to exhibit consistent 513 behavior, you need to specify this 514 515 <span>method</span> 516 for all of the environment handles used in your application. 517 </p> 518 <p> 519 You can achieve this behavior on a transaction by transaction basis by 520 521 522 <span> 523 using <tt class="methodname">Transaction.commitNoSync()</tt> 524 525 to commit your transaction, or by specifying <tt class="literal">true</tt> to the 526 <tt class="methodname">TransactionConfig.setNoSync()</tt> method when starting the 527 transaction. 528 </span> 529 530 </p> 531 </li> 532 <li> 533 <p> 534 Specify 535 536 537 <span> 538 <tt class="literal">true</tt> to the 539 <tt class="methodname">EnvironmentConfig.setTxnWriteNoSync()</tt> 540 method. 541 </span> 542 543 This causes 544 <span> 545 logging 546 </span> 547 data to be synchronously 548 written to the OS's file system buffers upon 549 transaction commit. The data will eventually be 550 written to disk, but this occurs when the 551 operating system chooses to schedule the 552 activity; the transaction commit can complete 553 successfully before this disk I/O is performed 554 by the OS. 555 </p> 556 <p> 557 This form of commit protects you against application 558 <span>and JVM</span> crashes, but not against OS 559 crashes. This method offers less room for the possibility of data loss than does 560 561 <span><tt class="methodname">EnvironmentConfig.setTxnNoSync()</tt>.</span> 562 </p> 563 <p> 564 This behavior is specified on a per-environment 565 handle basis. In order for your application to exhibit consistent 566 behavior, you need to specify this 567 568 <span>method</span> 569 for all of the environment handles used in your application. 570 </p> 571 <p> 572 You can achieve this behavior on a transaction by transaction basis by 573 <span> 574 using <tt class="methodname">Transaction.commitWriteNoSync()</tt> 575 to commit your transaction, or by specifying <tt class="literal">true</tt> to 576 <tt class="methodname">TransactionConfig.setWriteNoSync()</tt> method when starting the 577 transaction. 578 </span> 579 </p> 580 </li> 581 <li> 582 <p> 583 Maintain your logs entirely in-memory. In this 584 case, your logs are never written to disk. The 585 result is that you lose all durability guarantees. 586 See 587 <a href="logconfig.html#inmemorylogging">Configuring In-Memory Logging</a> 588 for more information. 589 </p> 590 </li> 591 </ul> 592 </div> 593 </div> 594 </div> 595 </div> 596 <div class="navfooter"> 597 <hr /> 598 <table width="100%" summary="Navigation footer"> 599 <tr> 600 <td width="40%" align="left"><a accesskey="p" href="envopen.html">Prev</a> </td> 601 <td width="20%" align="center"> 602 <a accesskey="u" href="index.html">Up</a> 603 </td> 604 <td width="40%" align="right"> <a accesskey="n" href="abortresults.html">Next</a></td> 605 </tr> 606 <tr> 607 <td width="40%" align="left" valign="top">Opening a Transactional Environment and 608 609 Store or Database 610 611 </td> 612 <td width="20%" align="center"> 613 <a accesskey="h" href="index.html">Home</a> 614 </td> 615 <td width="40%" align="right" valign="top"> Aborting a Transaction</td> 616 </tr> 617 </table> 618 </div> 619 </body> 620</html> 621