1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002,2008 Oracle. All rights reserved. 5 * 6 * $Id: Transaction.java,v 12.9 2008/01/17 05:04:53 mjc Exp $ 7 */ 8 9package com.sleepycat.db; 10 11import com.sleepycat.db.internal.DbConstants; 12import com.sleepycat.db.internal.DbTxn; 13 14/** 15The Transaction object is the handle for a transaction. Methods off the 16transaction handle are used to configure, abort and commit the 17transaction. Transaction handles are provided to other Berkeley DB 18methods in order to transactionally protect those operations. 19<p> 20Transaction handles are not free-threaded; transactions handles may 21be used by multiple threads, but only serially, that is, the application 22must serialize access to the handle. Once the 23{@link com.sleepycat.db.Transaction#abort Transaction.abort}, {@link com.sleepycat.db.Transaction#commit Transaction.commit} or 24{@link com.sleepycat.db.Transaction#discard Transaction.discard} 25methods are called, the handle may 26not be accessed again, regardless of the success or failure of the method. 27In addition, parent transactions may not issue any Berkeley DB operations 28while they have active child transactions (child transactions that have 29not yet been committed or aborted) except for {@link com.sleepycat.db.Environment#beginTransaction Environment.beginTransaction}, {@link com.sleepycat.db.Transaction#abort Transaction.abort} and {@link com.sleepycat.db.Transaction#commit Transaction.commit}. 30<p> 31To obtain a transaction with default attributes: 32<blockquote><pre> 33 Transaction txn = myEnvironment.beginTransaction(null, null); 34</pre></blockquote> 35To customize the attributes of a transaction: 36<blockquote><pre> 37 TransactionConfig config = new TransactionConfig(); 38 config.setDirtyRead(true); 39 Transaction txn = myEnvironment.beginTransaction(null, config); 40</pre></blockquote> 41*/ 42public class Transaction { 43 /*package */ final DbTxn txn; 44 45 Transaction(final DbTxn txn) { 46 this.txn = txn; 47 } 48 49 /** 50 Cause an abnormal termination of the transaction. 51 <p> 52 The log is played backward, and any necessary undo operations are done. 53 Before Transaction.abort returns, any locks held by the transaction will 54 have been released. 55 <p> 56 In the case of nested transactions, aborting a parent transaction 57 causes all children (unresolved or not) of the parent transaction 58 to be aborted. 59 <p> 60 All cursors opened within the transaction must be closed before the 61 transaction is aborted. 62 <p> 63 After Transaction.abort has been called, regardless of its return, the 64 {@link com.sleepycat.db.Transaction Transaction} handle may not be accessed again. 65 <p> 66 <p> 67@throws DatabaseException if a failure occurs. 68 */ 69 public void abort() 70 throws DatabaseException { 71 72 txn.abort(); 73 } 74 75 /** 76 End the transaction. If the environment is configured for synchronous 77commit, the transaction will be committed synchronously to stable 78storage before the call returns. This means the transaction will exhibit 79all of the ACID (atomicity, consistency, isolation, and durability) 80properties. 81<p> 82If the environment is not configured for synchronous commit, the commit 83will not necessarily have been committed to stable storage before the 84call returns. This means the transaction will exhibit the ACI (atomicity, 85consistency, and isolation) properties, but not D (durability); that is, 86database integrity will be maintained, but it is possible this transaction 87may be undone during recovery. 88<p> 89In the case of nested transactions, if the transaction is a parent 90transaction, committing the parent transaction causes all unresolved 91children of the parent to be committed. In the case of nested 92transactions, if the transaction is a child transaction, its locks are 93not released, but are acquired by its parent. Although the commit of the 94child transaction will succeed, the actual resolution of the child 95transaction is postponed until the parent transaction is committed or 96aborted; that is, if its parent transaction commits, it will be 97committed; and if its parent transaction aborts, it will be aborted. 98<p> 99All cursors opened within the transaction must be closed before the 100transaction is committed. 101<p> 102After this method returns the {@link com.sleepycat.db.Transaction Transaction} handle may not be 103accessed again, regardless of the method's success or failure. If the 104method encounters an error, the transaction and all child transactions 105of the transaction will have been aborted when the call returns. 106<p> 107<p> 108@throws DatabaseException if a failure occurs. 109 */ 110 public void commit() 111 throws DatabaseException { 112 113 txn.commit(0); 114 } 115 116 /** 117 End the transaction, committing synchronously. This means the 118transaction will exhibit all of the ACID (atomicity, consistency, 119isolation, and durability) properties. 120<p> 121This behavior is the default for database environments unless otherwise 122configured using the {@link com.sleepycat.db.EnvironmentConfig#setTxnNoSync EnvironmentConfig.setTxnNoSync} method. This 123behavior may also be set for a single transaction using the 124{@link com.sleepycat.db.Environment#beginTransaction Environment.beginTransaction} method. Any value specified to 125this method overrides both of those settings. 126<p> 127In the case of nested transactions, if the transaction is a parent 128transaction, committing the parent transaction causes all unresolved 129children of the parent to be committed. In the case of nested 130transactions, if the transaction is a child transaction, its locks are 131not released, but are acquired by its parent. Although the commit of the 132child transaction will succeed, the actual resolution of the child 133transaction is postponed until the parent transaction is committed or 134aborted; that is, if its parent transaction commits, it will be 135committed; and if its parent transaction aborts, it will be aborted. 136<p> 137All cursors opened within the transaction must be closed before the 138transaction is committed. 139<p> 140After this method returns the {@link com.sleepycat.db.Transaction Transaction} handle may not be 141accessed again, regardless of the method's success or failure. If the 142method encounters an error, the transaction and all child transactions 143of the transaction will have been aborted when the call returns. 144<p> 145<p> 146@throws DatabaseException if a failure occurs. 147 */ 148 public void commitSync() 149 throws DatabaseException { 150 151 txn.commit(DbConstants.DB_TXN_SYNC); 152 } 153 154 /** 155 End the transaction, not committing synchronously. 156This means the 157transaction will exhibit the ACI (atomicity, consistency, and isolation) 158properties, but not D (durability); that is, database integrity will be 159maintained, but it is possible this transaction may be undone during 160recovery. 161<p> 162This behavior may be set for a database environment using the 163{@link com.sleepycat.db.EnvironmentConfig#setTxnNoSync EnvironmentConfig.setTxnNoSync} method or for a single transaction 164using the {@link com.sleepycat.db.Environment#beginTransaction Environment.beginTransaction} method. Any value 165specified to this method overrides both of those settings. 166<p> 167In the case of nested transactions, if the transaction is a parent 168transaction, committing the parent transaction causes all unresolved 169children of the parent to be committed. In the case of nested 170transactions, if the transaction is a child transaction, its locks are 171not released, but are acquired by its parent. Although the commit of the 172child transaction will succeed, the actual resolution of the child 173transaction is postponed until the parent transaction is committed or 174aborted; that is, if its parent transaction commits, it will be 175committed; and if its parent transaction aborts, it will be aborted. 176<p> 177All cursors opened within the transaction must be closed before the 178transaction is committed. 179<p> 180After this method returns the {@link com.sleepycat.db.Transaction Transaction} handle may not be 181accessed again, regardless of the method's success or failure. If the 182method encounters an error, the transaction and all child transactions 183of the transaction will have been aborted when the call returns. 184<p> 185<p> 186@throws DatabaseException if a failure occurs. 187 */ 188 public void commitNoSync() 189 throws DatabaseException { 190 191 txn.commit(DbConstants.DB_TXN_NOSYNC); 192 } 193 194 /** 195 End the transaction, writing but not flushing the log. 196This means the 197transaction will exhibit the ACI (atomicity, consistency, and isolation) 198properties, but not D (durability); that is, database integrity will be 199maintained, but it is possible this transaction may be undone during 200recovery in the event that the operating system crashes. This option 201provides more durability than an asynchronous commit and has less 202performance cost than a synchronous commit. 203<p> 204This behavior may be set for a database environment using the 205{@link com.sleepycat.db.EnvironmentConfig#setTxnWriteNoSync EnvironmentConfig.setTxnWriteNoSync} method or for a single 206transaction using the {@link com.sleepycat.db.Environment#beginTransaction Environment.beginTransaction} method. 207Any value specified to this method overrides both of those settings. 208<p> 209In the case of nested transactions, if the transaction is a parent 210transaction, committing the parent transaction causes all unresolved 211children of the parent to be committed. In the case of nested 212transactions, if the transaction is a child transaction, its locks are 213not released, but are acquired by its parent. Although the commit of the 214child transaction will succeed, the actual resolution of the child 215transaction is postponed until the parent transaction is committed or 216aborted; that is, if its parent transaction commits, it will be 217committed; and if its parent transaction aborts, it will be aborted. 218<p> 219All cursors opened within the transaction must be closed before the 220transaction is committed. 221<p> 222After this method returns the {@link com.sleepycat.db.Transaction Transaction} handle may not be 223accessed again, regardless of the method's success or failure. If the 224method encounters an error, the transaction and all child transactions 225of the transaction will have been aborted when the call returns. 226<p> 227<p> 228@throws DatabaseException if a failure occurs. 229 */ 230 public void commitWriteNoSync() 231 throws DatabaseException { 232 233 txn.commit(DbConstants.DB_TXN_WRITE_NOSYNC); 234 } 235 236 /** 237 Free up all the per-process resources associated with the specified 238 {@link com.sleepycat.db.Transaction Transaction} handle, neither committing nor aborting the 239 transaction. This call may be used only after calls to 240 {@link com.sleepycat.db.Environment#recover Environment.recover} when there are multiple global 241 transaction managers recovering transactions in a single database 242 environment. Any transactions returned by {@link com.sleepycat.db.Environment#recover Environment.recover} that are not handled by the current global transaction 243 manager should be discarded using this method. 244 <p> 245 The {@link com.sleepycat.db.Transaction Transaction} handle may not be accessed again after this 246 method has been called, regardless of the method's success or failure. 247 <p> 248 <p> 249@throws DatabaseException if a failure occurs. 250 */ 251 public void discard() 252 throws DatabaseException { 253 254 txn.discard(0); 255 } 256 257 /** 258 Return the transaction's unique ID. 259 <p> 260 Locking calls made on behalf of this transaction should use the 261 value returned from this method as the locker parameter to the 262 {@link com.sleepycat.db.Environment#getLock Environment.getLock} or {@link com.sleepycat.db.Environment#lockVector Environment.lockVector} 263 calls. 264 <p> 265 @return 266 The transaction's unique ID. 267 <p> 268 <p> 269@throws DatabaseException if a failure occurs. 270 */ 271 public int getId() 272 throws DatabaseException { 273 274 return txn.id(); 275 } 276 277 /** 278 Get the user visible name for the transaction. 279 <p> 280 @return 281 The user visible name for the transaction. 282 <p> 283 */ 284 public String getName() 285 throws DatabaseException { 286 287 return txn.get_name(); 288 } 289 290 /** 291 Initiate the beginning of a two-phase commit. 292 <p> 293 In a distributed transaction environment, Berkeley DB can be used 294 as a local transaction manager. In this case, the distributed 295 transaction manager must send <em>prepare</em> messages to each 296 local manager. The local manager must then issue a 297 {@link com.sleepycat.db.Transaction#prepare Transaction.prepare} call and await its successful return 298 before responding to the distributed transaction manager. Only 299 after the distributed transaction manager receives successful 300 responses from all of its <em>prepare</em> messages should it issue 301 any <em>commit</em> messages. 302 <p> 303 In the case of nested transactions, preparing the parent causes all 304 unresolved children of the parent transaction to be committed. 305 Child transactions should never be explicitly prepared. Their fate 306 will be resolved along with their parent's during global recovery. 307 <p> 308 @param gid 309 The global transaction ID by which this transaction will be known. 310 This global transaction ID will be returned in calls to 311 {@link com.sleepycat.db.Environment#recover Environment.recover} method, telling the application which 312 global transactions must be resolved. The gid parameter must be sized 313 at least DB_XIDDATASIZE (currently 128) bytes; only the first 314 DB_XIDDATASIZE bytes are used. 315 <p> 316 <p> 317@throws DatabaseException if a failure occurs. 318 */ 319 public void prepare(final byte[] gid) 320 throws DatabaseException { 321 322 txn.prepare(gid); 323 } 324 325 /** 326 Set the user visible name for the transaction. 327 <p> 328 @param name 329 The user visible name for the transaction. 330 <p> 331 */ 332 public void setName(final String name) 333 throws DatabaseException { 334 335 txn.set_name(name); 336 } 337 338 /** 339 Configure the timeout value for the transaction lifetime. 340 <p> 341 If the transaction runs longer than this time, the transaction may 342 may throw {@link com.sleepycat.db.DatabaseException DatabaseException}. 343 <p> 344 Timeouts are checked whenever a thread of control blocks on a lock 345 or when deadlock detection is performed. For this reason, the 346 accuracy of the timeout depends on how often deadlock detection is 347 performed. 348 <p> 349 @param timeOut 350 The timeout value for the transaction lifetime, in microseconds. As 351 the value is an unsigned 32-bit number of microseconds, the maximum 352 timeout is roughly 71 minutes. A value of 0 disables timeouts for 353 the transaction. 354 <p> 355 This method may be called at any time during the life of the application. 356 <p> 357 <p> 358@throws DatabaseException if a failure occurs. 359 */ 360 public void setTxnTimeout(final long timeOut) 361 throws DatabaseException { 362 363 txn.set_timeout(timeOut, DbConstants.DB_SET_TXN_TIMEOUT); 364 } 365 366 /** 367 Configure the lock request timeout value for the transaction. 368 <p> 369 If a lock request cannot be granted in this time, the transaction 370 may throw {@link com.sleepycat.db.DatabaseException DatabaseException}. 371 <p> 372 Timeouts are checked whenever a thread of control blocks on a lock 373 or when deadlock detection is performed. For this reason, the 374 accuracy of the timeout depends on how often deadlock detection is 375 performed. 376 <p> 377 @param timeOut 378 The lock request timeout value for the transaction, in microseconds. 379 As the value is an unsigned 32-bit number of microseconds, the maximum 380 timeout is roughly 71 minutes. A value of 0 disables timeouts for the 381 transaction. 382 <p> 383 This method may be called at any time during the life of the application. 384 <p> 385 <p> 386@throws DatabaseException if a failure occurs. 387 */ 388 public void setLockTimeout(final long timeOut) 389 throws DatabaseException { 390 391 txn.set_timeout(timeOut, DbConstants.DB_SET_LOCK_TIMEOUT); 392 } 393} 394