/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2009 Oracle. All rights reserved. * */ using System; using System.Collections.Generic; using System.Text; using BerkeleyDB.Internal; namespace BerkeleyDB { /// /// A class representing Berkeley DB transactions /// /// /// /// Calling , /// or /// will release the resources held by /// the created object. /// /// /// Transactions may only span threads if they do so serially; that is, /// each transaction must be active in only a single thread of control /// at a time. This restriction holds for parents of nested transactions /// as well; no two children may be concurrently active in more than one /// thread of control at any one time. /// /// /// Cursors may not span transactions; that is, each cursor must be /// opened and closed within a single transaction. /// /// /// A parent transaction may not issue any Berkeley DB operations — /// except for , /// and /// — while it has active child transactions (child transactions that /// have not yet been committed or aborted). /// /// public class Transaction { /// /// The size of the global transaction ID /// public static uint GlobalIdLength = DbConstants.DB_GID_SIZE; internal DB_TXN dbtxn; internal Transaction(DB_TXN txn) { dbtxn = txn; } private bool idCached = false; private uint _id; /// /// The unique transaction id associated with this transaction. /// public uint Id { get { if (!idCached) { _id = dbtxn.id(); idCached = true; } return _id; } } /// /// Cause an abnormal termination of the transaction. /// /// /// /// Before Abort returns, any locks held by the transaction will have /// been released. /// /// /// In the case of nested transactions, aborting a parent transaction /// causes all children (unresolved or not) of the parent transaction to /// be aborted. /// /// /// All cursors opened within the transaction must be closed before the /// transaction is aborted. /// /// public void Abort() { dbtxn.abort(); } /// /// End the transaction. /// /// /// /// In the case of nested transactions, if the transaction is a parent /// transaction, committing the parent transaction causes all unresolved /// children of the parent to be committed. In the case of nested /// transactions, if the transaction is a child transaction, its locks /// are not released, but are acquired by its parent. Although the /// commit of the child transaction will succeed, the actual resolution /// of the child transaction is postponed until the parent transaction /// is committed or aborted; that is, if its parent transaction commits, /// it will be committed; and if its parent transaction aborts, it will /// be aborted. /// /// /// All cursors opened within the transaction must be closed before the /// transaction is committed. /// /// public void Commit() { dbtxn.commit(0); } /// /// End the transaction. /// /// /// Synchronously flushing the log is the default for Berkeley DB /// environments unless /// was specified. /// Synchronous log flushing may also be set or unset for a single /// transaction using /// . The /// value of overrides both of those /// settings. /// /// If true, synchronously flush the log. public void Commit(bool syncLog) { dbtxn.commit( syncLog ? DbConstants.DB_TXN_SYNC : DbConstants.DB_TXN_NOSYNC); } /// /// Free up all the per-process resources associated with the specified /// Transaction instance, neither committing nor aborting the /// transaction. /// /// /// This call may be used only after calls to /// when there are multiple /// global transaction managers recovering transactions in a single /// Berkeley DB environment. Any transactions returned by /// that are not handled by /// the current global transaction manager should be discarded using /// Discard. /// public void Discard() { dbtxn.discard(0); } /// /// The transaction's name. The name is returned by /// /// and displayed by /// . /// /// /// If the database environment has been configured for logging and the /// Berkeley DB library was built in Debug mode (or with DIAGNOSTIC /// defined), a debugging log record is written including the /// transaction ID and the name. /// public string Name { get { string ret = ""; dbtxn.get_name(ref ret); return ret; } set { dbtxn.set_name(value); } } /// /// Initiate the beginning of a two-phase commit. /// /// /// /// In a distributed transaction environment, Berkeley DB can be used as /// a local transaction manager. In this case, the distributed /// transaction manager must send prepare messages to each local /// manager. The local manager must then call Prepare and await its /// successful return before responding to the distributed transaction /// manager. Only after the distributed transaction manager receives /// successful responses from all of its prepare messages should it /// issue any commit messages. /// /// /// In the case of nested transactions, preparing the parent causes all /// unresolved children of the parent transaction to be committed. Child /// transactions should never be explicitly prepared. Their fate will be /// resolved along with their parent's during global recovery. /// /// /// /// The global transaction ID by which this transaction will be known. /// This global transaction ID will be returned in calls to /// telling the /// application which global transactions must be resolved. /// public void Prepare(byte[] globalId) { if (globalId.Length != Transaction.GlobalIdLength) throw new ArgumentException( "Global ID length must be " + Transaction.GlobalIdLength); dbtxn.prepare(globalId); } /// /// Set the timeout value for locks for this transaction. /// /// /// /// Timeouts are checked whenever a thread of control blocks on a lock /// or when deadlock detection is performed. This timeout is for any /// single lock request. As timeouts are only checked when the lock /// request first blocks or when deadlock detection is performed, the /// accuracy of the timeout depends on how often deadlock detection is /// performed. /// /// /// Timeout values may be specified for the database environment as a /// whole. See for more /// information. /// /// /// /// An unsigned 32-bit number of microseconds, limiting the maximum /// timeout to roughly 71 minutes. A value of 0 disables timeouts for /// the transaction. /// public void SetLockTimeout(uint timeout) { dbtxn.set_timeout(timeout, DbConstants.DB_SET_LOCK_TIMEOUT); } /// /// Set the timeout value for transactions for this transaction. /// /// /// /// Timeouts are checked whenever a thread of control blocks on a lock /// or when deadlock detection is performed. This timeout is for the /// life of the transaction. As timeouts are only checked when the lock /// request first blocks or when deadlock detection is performed, the /// accuracy of the timeout depends on how often deadlock detection is /// performed. /// /// /// Timeout values may be specified for the database environment as a /// whole. See for more /// information. /// /// /// /// An unsigned 32-bit number of microseconds, limiting the maximum /// timeout to roughly 71 minutes. A value of 0 disables timeouts for /// the transaction. /// public void SetTxnTimeout(uint timeout) { dbtxn.set_timeout(timeout, DbConstants.DB_SET_TXN_TIMEOUT); } static internal DB_TXN getDB_TXN(Transaction txn) { return txn == null ? null : txn.dbtxn; } } }