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