1 /*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002, 2014 Oracle and/or its affiliates. All rights reserved. 5 * 6 */ 7 8 package com.sleepycat.je; 9 10 import com.sleepycat.je.dbi.EnvironmentImpl; 11 12 /** 13 * Specifies the attributes of a database environment transaction. 14 */ 15 public class TransactionConfig implements Cloneable { 16 17 /** 18 * Default configuration used if null is passed to methods that create a 19 * transaction. 20 */ 21 public static final TransactionConfig DEFAULT = new TransactionConfig(); 22 23 private boolean sync = false; 24 private boolean noSync = false; 25 private boolean writeNoSync = false; 26 private Durability durability = null; 27 private ReplicaConsistencyPolicy consistencyPolicy; 28 private boolean noWait = false; 29 private boolean readUncommitted = false; 30 private boolean readCommitted = false; 31 private boolean serializableIsolation = false; 32 private boolean readOnly = false; 33 private boolean localWrite = false; 34 35 /** 36 * An instance created using the default constructor is initialized with 37 * the system's default settings. 38 */ TransactionConfig()39 public TransactionConfig() { 40 } 41 42 /** 43 * @hidden 44 * For internal use only. 45 * 46 * Maps the existing sync settings to the equivalent durability settings. 47 * Figure out what we should do on commit. TransactionConfig could be 48 * set with conflicting values; take the most stringent ones first. 49 * All environment level defaults were applied by the caller. 50 * 51 * ConfigSync ConfigWriteNoSync ConfigNoSync default 52 * 0 0 0 sync 53 * 0 0 1 nosync 54 * 0 1 0 write nosync 55 * 0 1 1 write nosync 56 * 1 0 0 sync 57 * 1 0 1 sync 58 * 1 1 0 sync 59 * 1 1 1 sync 60 * 61 * @return the equivalent durability 62 */ getDurabilityFromSync(final EnvironmentImpl envImpl)63 public Durability getDurabilityFromSync(final EnvironmentImpl envImpl) { 64 if (sync) { 65 return Durability.COMMIT_SYNC; 66 } else if (writeNoSync) { 67 return Durability.COMMIT_WRITE_NO_SYNC; 68 } else if (noSync) { 69 return Durability.COMMIT_NO_SYNC; 70 } 71 72 /* 73 * Replicated environments default to commitNoSync, while standalone 74 * default to commitSync. 75 */ 76 if (envImpl.isReplicated()) { 77 return Durability.COMMIT_NO_SYNC; 78 } else { 79 return Durability.COMMIT_SYNC; 80 } 81 } 82 83 /** 84 * Configures the transaction to write and synchronously flush the log it 85 * when commits. 86 * 87 * <p>This behavior may be set for a database environment using the 88 * Environment.setMutableConfig method. Any value specified to this method 89 * overrides that setting.</p> 90 * 91 * <p>The default is false for this class and true for the database 92 * environment.</p> 93 * 94 * <p>If true is passed to both setSync and setNoSync, setSync will take 95 * precedence.</p> 96 * 97 * @param sync If true, transactions exhibit all the ACID (atomicity, 98 * consistency, isolation, and durability) properties. 99 * 100 * @return this 101 */ setSync(final boolean sync)102 public TransactionConfig setSync(final boolean sync) { 103 setSyncVoid(sync); 104 return this; 105 } 106 107 /** 108 * @hidden 109 * The void return setter for use by Bean editors. 110 */ setSyncVoid(final boolean sync)111 public void setSyncVoid(final boolean sync) { 112 checkMixedMode(sync, noSync, writeNoSync, durability); 113 this.sync = sync; 114 } 115 116 /** 117 * Returns true if the transaction is configured to write and synchronously 118 * flush the log it when commits. 119 * 120 * @return true if the transaction is configured to write and synchronously 121 * flush the log it when commits. 122 */ getSync()123 public boolean getSync() { 124 return sync; 125 } 126 127 /** 128 * Configures the transaction to not write or synchronously flush the log 129 * it when commits. 130 * 131 * <p>This behavior may be set for a database environment using the 132 * Environment.setMutableConfig method. Any value specified to this method 133 * overrides that setting.</p> 134 * 135 * <p>The default is false for this class and the database environment.</p> 136 * 137 * @param noSync If true, transactions exhibit the ACI (atomicity, 138 * consistency, and isolation) properties, but not D (durability); that is, 139 * database integrity will be maintained, but if the application or system 140 * fails, it is possible some number of the most recently committed 141 * transactions may be undone during recovery. The number of transactions 142 * at risk is governed by how many log updates can fit into the log buffer, 143 * how often the operating system flushes dirty buffers to disk, and how 144 * often the log is checkpointed. 145 * 146 * @deprecated replaced by {@link #setDurability} 147 * 148 * @return this 149 */ setNoSync(final boolean noSync)150 public TransactionConfig setNoSync(final boolean noSync) { 151 setNoSyncVoid(noSync); 152 return this; 153 } 154 155 /** 156 * @hidden 157 * The void return setter for use by Bean editors. 158 */ setNoSyncVoid(final boolean noSync)159 public void setNoSyncVoid(final boolean noSync) { 160 checkMixedMode(sync, noSync, writeNoSync, durability); 161 this.noSync = noSync; 162 } 163 164 /** 165 * Returns true if the transaction is configured to not write or 166 * synchronously flush the log it when commits. 167 * 168 * @return true if the transaction is configured to not write or 169 * synchronously flush the log it when commits. 170 * 171 * @deprecated replaced by {@link #getDurability} 172 */ getNoSync()173 public boolean getNoSync() { 174 return noSync; 175 } 176 177 /** 178 * Configures the transaction to write but not synchronously flush the log 179 * it when commits. 180 * 181 * <p>This behavior may be set for a database environment using the 182 * Environment.setMutableConfig method. Any value specified to this method 183 * overrides that setting.</p> 184 * 185 * <p>The default is false for this class and the database environment.</p> 186 * 187 * @param writeNoSync If true, transactions exhibit the ACI (atomicity, 188 * consistency, and isolation) properties, but not D (durability); that is, 189 * database integrity will be maintained, but if the operating system 190 * fails, it is possible some number of the most recently committed 191 * transactions may be undone during recovery. The number of transactions 192 * at risk is governed by how often the operating system flushes dirty 193 * buffers to disk, and how often the log is checkpointed. 194 * 195 * @deprecated replaced by {@link #setDurability} 196 * 197 * @return this 198 */ setWriteNoSync(final boolean writeNoSync)199 public TransactionConfig setWriteNoSync(final boolean writeNoSync) { 200 setWriteNoSyncVoid(writeNoSync); 201 return this; 202 } 203 204 /** 205 * @hidden 206 * The void return setter for use by Bean editors. 207 */ setWriteNoSyncVoid(final boolean writeNoSync)208 public void setWriteNoSyncVoid(final boolean writeNoSync) { 209 checkMixedMode(sync, noSync, writeNoSync, durability); 210 this.writeNoSync = writeNoSync; 211 } 212 213 /** 214 * Returns true if the transaction is configured to write but not 215 * synchronously flush the log it when commits. 216 * 217 * @return true if the transaction is configured to not write or 218 * synchronously flush the log it when commits. 219 * 220 * @deprecated replaced by {@link #getDurability} 221 */ getWriteNoSync()222 public boolean getWriteNoSync() { 223 return writeNoSync; 224 } 225 226 /** 227 * Configures the durability associated with a transaction when it commits. 228 * Changes to durability are not reflected back to the "sync" booleans -- 229 * there isn't a one to one mapping. 230 * 231 * Note that you should not use both the durability and the XXXSync() apis 232 * on the same config object. 233 * 234 * @param durability the durability definition 235 * 236 * @return this 237 */ setDurability(final Durability durability)238 public TransactionConfig setDurability(final Durability durability) { 239 setDurabilityVoid(durability); 240 return this; 241 } 242 243 /** 244 * @hidden 245 * The void return setter for use by Bean editors. 246 */ setDurabilityVoid(final Durability durability)247 public void setDurabilityVoid(final Durability durability) { 248 checkMixedMode(sync, noSync, writeNoSync, durability); 249 this.durability = durability; 250 } 251 252 /** 253 * Returns the durability associated with the configuration. 254 * 255 * If {@link #setDurability} has not been called, this method returns null. 256 * When no durability settings have been specified using the 257 * {@code TransactionConfig}, the default durability is applied to the 258 * {@link Transaction} by {@link Environment#beginTransaction} using 259 * {@link EnvironmentConfig} settings. 260 * 261 * @return the durability setting currently associated with this config. 262 */ getDurability()263 public Durability getDurability() { 264 return durability; 265 } 266 267 /** 268 * Used internally to configure Durability, modifying the existing 269 * Durability or explicit sync configuration. This method is used to avoid 270 * a mixed mode exception, since the existing config may be in either mode. 271 */ overrideDurability(final Durability durability)272 void overrideDurability(final Durability durability) { 273 sync = false; 274 noSync = false; 275 writeNoSync = false; 276 this.durability = durability; 277 } 278 279 /** 280 * Associates a consistency policy with this configuration. 281 * 282 * @param consistencyPolicy the consistency definition 283 * 284 * @return this 285 */ setConsistencyPolicy( final ReplicaConsistencyPolicy consistencyPolicy)286 public TransactionConfig setConsistencyPolicy( 287 final ReplicaConsistencyPolicy consistencyPolicy) { 288 289 setConsistencyPolicyVoid(consistencyPolicy); 290 return this; 291 } 292 293 /** 294 * @hidden 295 * The void return setter for use by Bean editors. 296 */ setConsistencyPolicyVoid( final ReplicaConsistencyPolicy consistencyPolicy)297 public void setConsistencyPolicyVoid( 298 final ReplicaConsistencyPolicy consistencyPolicy) { 299 300 this.consistencyPolicy = consistencyPolicy; 301 } 302 /** 303 * Returns the consistency policy associated with the configuration. 304 * 305 * @return the consistency policy currently associated with this config. 306 */ getConsistencyPolicy()307 public ReplicaConsistencyPolicy getConsistencyPolicy() { 308 return consistencyPolicy; 309 } 310 311 /** 312 * Configures the transaction to not wait if a lock request cannot be 313 * immediately granted. 314 * 315 * <p>The default is false for this class and the database environment.</p> 316 * 317 * @param noWait If true, transactions will not wait if a lock request 318 * cannot be immediately granted, instead {@link 319 * com.sleepycat.je.LockNotAvailableException LockNotAvailableException} 320 * will be thrown. 321 * 322 * @return this 323 */ setNoWait(final boolean noWait)324 public TransactionConfig setNoWait(final boolean noWait) { 325 setNoWaitVoid(noWait); 326 return this; 327 } 328 329 /** 330 * @hidden 331 * The void return setter for use by Bean editors. 332 */ setNoWaitVoid(final boolean noWait)333 public void setNoWaitVoid(final boolean noWait) { 334 this.noWait = noWait; 335 } 336 337 /** 338 * Returns true if the transaction is configured to not wait if a lock 339 * request cannot be immediately granted. 340 * 341 * @return true if the transaction is configured to not wait if a lock 342 * request cannot be immediately granted. 343 */ getNoWait()344 public boolean getNoWait() { 345 return noWait; 346 } 347 348 /** 349 * Configures read operations performed by the transaction to return 350 * modified but not yet committed data. 351 * 352 * @param readUncommitted If true, configure read operations performed by 353 * the transaction to return modified but not yet committed data. 354 * 355 * @see LockMode#READ_UNCOMMITTED 356 * 357 * @return this 358 */ setReadUncommitted( final boolean readUncommitted)359 public TransactionConfig setReadUncommitted( 360 final boolean readUncommitted) { 361 362 setReadUncommittedVoid(readUncommitted); 363 return this; 364 } 365 366 /** 367 * @hidden 368 * The void return setter for use by Bean editors. 369 */ setReadUncommittedVoid(final boolean readUncommitted)370 public void setReadUncommittedVoid(final boolean readUncommitted) { 371 this.readUncommitted = readUncommitted; 372 } 373 374 /** 375 * Returns true if read operations performed by the transaction are 376 * configured to return modified but not yet committed data. 377 * 378 * @return true if read operations performed by the transaction are 379 * configured to return modified but not yet committed data. 380 * 381 * @see LockMode#READ_UNCOMMITTED 382 */ getReadUncommitted()383 public boolean getReadUncommitted() { 384 return readUncommitted; 385 } 386 387 /** 388 * Configures the transaction for read committed isolation. 389 * 390 * <p>This ensures the stability of the current data item read by the 391 * cursor but permits data read by this transaction to be modified or 392 * deleted prior to the commit of the transaction.</p> 393 * 394 * @param readCommitted If true, configure the transaction for read 395 * committed isolation. 396 * 397 * @see LockMode#READ_COMMITTED 398 * 399 * @return this 400 */ setReadCommitted(final boolean readCommitted)401 public TransactionConfig setReadCommitted(final boolean readCommitted) { 402 setReadCommittedVoid(readCommitted); 403 return this; 404 } 405 406 /** 407 * @hidden 408 * The void return setter for use by Bean editors. 409 */ setReadCommittedVoid(final boolean readCommitted)410 public void setReadCommittedVoid(final boolean readCommitted) { 411 this.readCommitted = readCommitted; 412 } 413 414 /** 415 * Returns true if the transaction is configured for read committed 416 * isolation. 417 * 418 * @return true if the transaction is configured for read committed 419 * isolation. 420 * 421 * @see LockMode#READ_COMMITTED 422 */ getReadCommitted()423 public boolean getReadCommitted() { 424 return readCommitted; 425 } 426 427 /** 428 * Configures this transaction to have serializable (degree 3) isolation. 429 * By setting serializable isolation, phantoms will be prevented. 430 * 431 * <p>By default a transaction provides Repeatable Read isolation; {@link 432 * EnvironmentConfig#setTxnSerializableIsolation} may be called to override 433 * the default. If the environment is configured for serializable 434 * isolation, all transactions will be serializable regardless of whether 435 * this method is called; calling {@link #setSerializableIsolation} with a 436 * false parameter will not disable serializable isolation.</p> 437 * 438 * The default is false for this class and the database environment. 439 * 440 * @see LockMode 441 * 442 * @return this 443 */ setSerializableIsolation( final boolean serializableIsolation)444 public TransactionConfig setSerializableIsolation( 445 final boolean serializableIsolation) { 446 447 setSerializableIsolationVoid(serializableIsolation); 448 return this; 449 } 450 451 /** 452 * @hidden 453 * The void return setter for use by Bean editors. 454 */ setSerializableIsolationVoid( final boolean serializableIsolation)455 public void setSerializableIsolationVoid( 456 final boolean serializableIsolation) { 457 458 this.serializableIsolation = serializableIsolation; 459 } 460 461 /** 462 * Returns true if the transaction has been explicitly configured to have 463 * serializable (degree 3) isolation. 464 * 465 * @return true if the transaction has been configured to have serializable 466 * isolation. 467 * 468 * @see LockMode 469 */ getSerializableIsolation()470 public boolean getSerializableIsolation() { 471 return serializableIsolation; 472 } 473 474 /** 475 * Configures this transaction to disallow write operations, regardless of 476 * whether writes are allowed for the {@link Environment} or the 477 * {@link Database}s that are accessed. 478 * 479 * <p>If a write operation is attempted using a read-only transaction, 480 * an {@code UnsupportedOperationException} will be thrown.</p> 481 * 482 * <p>For a read-only transaction, the transaction's {@code Durability} is 483 * ignored, even when it is explicitly specified using {@link 484 * #setDurability(Durability)}.</p> 485 * 486 * <p>In a {@link com.sleepycat.je.rep.ReplicatedEnvironment}, a read-only 487 * transaction implicitly uses 488 * {@link com.sleepycat.je.Durability.ReplicaAckPolicy#NONE}. 489 * A read-only transaction on a Master will thus not be held up, or 490 * throw {@link com.sleepycat.je.rep.InsufficientReplicasException}, if the 491 * Master is not in contact with a sufficient number of Replicas at the 492 * time the transaction is initiated.</p> 493 * 494 * <p>The default setting is false (writes are allowed).</p> 495 * 496 * @return this 497 */ setReadOnly(final boolean readOnly)498 public TransactionConfig setReadOnly(final boolean readOnly) { 499 setReadOnlyVoid(readOnly); 500 return this; 501 } 502 503 /** 504 * @hidden 505 * The void return setter for use by Bean editors. 506 */ setReadOnlyVoid(final boolean readOnly)507 public void setReadOnlyVoid(final boolean readOnly) { 508 if (localWrite && readOnly) { 509 throw new IllegalArgumentException( 510 "localWrite and readOnly may not both be true"); 511 } 512 this.readOnly = readOnly; 513 } 514 515 /** 516 * Returns whether read-only is configured for this transaction. 517 */ getReadOnly()518 public boolean getReadOnly() { 519 return readOnly; 520 } 521 522 /** 523 * Configures this transaction to allow writing to non-replicated 524 * {@link Database}s in a 525 * {@link com.sleepycat.je.rep.ReplicatedEnvironment}. 526 * 527 * <p>In a replicated environment, a given transaction may be used to 528 * write to either replicated databases or non-replicated databases, but 529 * not both. If a write operation to a replicated database is attempted 530 * when local-write is true, or to a non-replicated database when 531 * local-write is false, an {@code UnsupportedOperationException} will be 532 * thrown.</p> 533 * 534 * <p>Note that for auto-commit transactions (when the {@code Transaction} 535 * parameter is null), the local-write setting is automatically set to 536 * correspond to whether the database is replicated. With auto-commit, 537 * local-write is always true for a non-replicated database, and 538 * always false for a replicated database.</p> 539 * 540 * <p>In a replicated environment, a local-write transaction implicitly 541 * uses {@link com.sleepycat.je.Durability.ReplicaAckPolicy#NONE}. 542 * A local-write transaction on a Master will thus not be held up, or 543 * throw {@link com.sleepycat.je.rep.InsufficientReplicasException}, if the 544 * Master is not in contact with a sufficient number of Replicas at the 545 * time the transaction is initiated.</p> 546 * 547 * <p>By default the local-write setting is false, meaning that the 548 * transaction may only write to replicated Databases in a replicated 549 * environment.</p> 550 * 551 * <p>This configuration setting is ignored in a non-replicated Environment 552 * since no databases are replicated.</p> 553 * 554 * @return this 555 * 556 * @see <a href="rep/ReplicatedEnvironment.html#nonRepDbs>Non-replicated 557 * Databases in a Replicated Environment</a> 558 */ setLocalWrite(final boolean localWrite)559 public TransactionConfig setLocalWrite(final boolean localWrite) { 560 setLocalWriteVoid(localWrite); 561 return this; 562 } 563 564 /** 565 * @hidden 566 * The void return setter for use by Bean editors. 567 */ setLocalWriteVoid(final boolean localWrite)568 public void setLocalWriteVoid(final boolean localWrite) { 569 if (localWrite && readOnly) { 570 throw new IllegalArgumentException( 571 "localWrite and readOnly may not both be true"); 572 } 573 this.localWrite = localWrite; 574 } 575 576 /** 577 * Returns whether local-write is configured for this transaction. 578 */ getLocalWrite()579 public boolean getLocalWrite() { 580 return localWrite; 581 } 582 583 /** 584 * Returns a copy of this configuration object. 585 */ 586 @Override clone()587 public TransactionConfig clone() { 588 try { 589 return (TransactionConfig) super.clone(); 590 } catch (CloneNotSupportedException willNeverOccur) { 591 return null; 592 } 593 } 594 595 /** 596 * 597 * Checks to catch mixing of deprecated and non-deprecated forms of the 598 * API. It's invoked before setting any of the config parameters. The 599 * arguments represent the new state of the durability configuration, 600 * before it has been changed. 601 * 602 * @throws IllegalArgumentException via TransactionConfig and 603 * EnvironmentMutableConfig setters 604 */ checkMixedMode(final boolean sync, final boolean noSync, final boolean writeNoSync, final Durability durability)605 static void checkMixedMode(final boolean sync, 606 final boolean noSync, 607 final boolean writeNoSync, 608 final Durability durability) 609 throws IllegalArgumentException { 610 611 if ((sync || noSync || writeNoSync) && (durability != null)) { 612 throw new IllegalArgumentException 613 ("Mixed use of deprecated and current durability APIs is " + 614 "not supported"); 615 } 616 617 if ((sync && noSync) || 618 (sync && writeNoSync) || 619 (noSync && writeNoSync)) { 620 throw new IllegalArgumentException 621 ("Only one of TxnSync, TxnNoSync, and TxnWriteNoSync " + 622 "can be set."); 623 } 624 } 625 626 /** 627 * Returns the values for each configuration attribute. 628 * 629 * @return the values for each configuration attribute. 630 */ 631 @Override toString()632 public String toString() { 633 return "sync=" + sync + 634 "\nnoSync=" + noSync + 635 "\nwriteNoSync=" + writeNoSync + 636 "\ndurability=" + durability + 637 "\nconsistencyPolicy=" + consistencyPolicy + 638 "\nnoWait=" + noWait + 639 "\nreadUncommitted=" + readUncommitted + 640 "\nreadCommitted=" + readCommitted + 641 "\nSerializableIsolation=" + serializableIsolation + 642 "\n"; 643 } 644 } 645