/*-
* 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;
}
}
}