// --------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // --------------------------------------------------------------------------- // --------------------------------------------------------------------- // // // --------------------------------------------------------------------- namespace Microsoft.Database.Isam { using System; /// /// A IsamTransaction object represents a single save point of a transaction /// that is begun on a Session object. This object is not required to /// begin, commit, or abort a transaction as this can be done directly /// on the Session object. However, this object is very useful for making /// convenient code constructs involving transactions with the "using" /// keyword in C# like this: /// /// using( IsamTransaction t = new IsamTransaction( session ) ) /// { /// /* do some work */ /// /// /* save the work */ /// t.Commit(); /// } /// /// public class IsamTransaction : IDisposable { /// /// The session /// private readonly IsamSession isamSession; /// /// The transaction level /// private readonly long transactionLevel; /// /// The transaction level identifier /// private readonly long transactionLevelID; /// /// The cleanup /// private bool cleanup = false; /// /// The disposed /// private bool disposed = false; /// /// Initializes a new instance of the class. /// Begin a transaction on the given session. /// /// /// The session we will use for the transaction. /// /// /// If this transaction is not committed before this object is disposed /// then the transaction will automatically be aborted. /// public IsamTransaction(IsamSession isamSession) { lock (isamSession) { this.isamSession = isamSession; this.isamSession.BeginTransaction(); this.transactionLevel = isamSession.TransactionLevel; this.transactionLevelID = isamSession.TransactionLevelID(isamSession.TransactionLevel); this.cleanup = true; } } /// /// Initializes a new instance of the class. /// Joins the current transaction on the given session. If the session /// is not currently in a transaction then a new transaction will be /// begun. /// /// /// The session we will use for the transaction. /// /// /// If true, the current transaction on the session will be joined. If false or if there is no current transaction then a new transaction will be begun. /// /// /// If an existing transaction is joined, then committing or aborting /// this transaction will have no effect on the joined transaction. If /// a new transaction was begun then these actions will work normally. /// /// If this transaction is not committed before this object is disposed /// then the transaction will automatically be aborted. /// /// public IsamTransaction(IsamSession isamSession, bool join) { lock (isamSession) { this.isamSession = isamSession; if (!join || isamSession.TransactionLevel == 0) { this.isamSession.BeginTransaction(); this.transactionLevel = isamSession.TransactionLevel; this.transactionLevelID = isamSession.TransactionLevelID(isamSession.TransactionLevel); this.cleanup = true; } } } /// /// Finalizes an instance of the IsamTransaction class /// ~IsamTransaction() { this.Dispose(false); } /// /// Gets the save point (level) for this transaction. /// public long TransactionLevel { get { this.CheckDisposed(); return this.transactionLevel; } } /// /// Gets or sets a value indicating whether [disposed]. /// /// /// true if [disposed]; otherwise, false. /// internal bool Disposed { get { return this.disposed || this.isamSession.Disposed || (this.cleanup && this.isamSession.TransactionLevelID(this.transactionLevel) != this.transactionLevelID); } set { this.disposed = value; } } /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// public void Dispose() { lock (this) { this.Dispose(true); } GC.SuppressFinalize(this); } /// /// Commits the save point (level) represented by this transaction on /// this session. All changes made to the database for this save point /// (level) will be kept. /// /// /// Changes made to the database will become permanent if and only if /// those changes are committed to save point (level) zero. /// /// A commit to save point (level) zero is guaranteed to be persisted /// to the database upon completion of this method. /// /// /// The transaction object will be disposed as a side effect of this /// call. /// /// public void Commit() { this.Commit(true); } /// /// Commits the save point (level) represented by this transaction on /// this session. All changes made to the database for this save point /// (level) will be kept. /// /// When true, a commit to save point (level) zero is guaranteed to be persisted to the database upon completion of this method. /// /// Changes made to the database will become permanent if and only if /// those changes are committed to save point (level) zero. /// /// A commit to save point (level) zero is guaranteed to be persisted /// to the database upon completion of this method only if /// durableCommit is true. If durableCommit is false then the changes /// will only be persisted to the database if their transaction log /// entries happen to be written to disk before a crash or if the /// database is shut down cleanly. /// /// /// The transaction object will be disposed as a side effect of this /// call. /// /// public void Commit(bool durableCommit) { lock (this.isamSession) { this.CheckDisposed(); if (this.cleanup) { this.isamSession.CommitTransaction(durableCommit); this.cleanup = false; } this.Dispose(); } } /// /// Aborts the save point (level) represented by this transaction on /// this session. All changes made to the database for this save point /// (level) will be discarded. /// /// /// The transaction object will be disposed as a side effect of this /// call. /// public void Rollback() { lock (this.isamSession) { this.CheckDisposed(); this.Dispose(); } } /// /// Aborts the save point (level) represented by this transaction on /// this session. All changes made to the database for this save point /// (level) will be discarded. /// /// /// The transaction object will be disposed as a side effect of this /// call. /// /// IsamTransaction.Abort is an alias for . /// /// public void Abort() { this.Rollback(); } /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// void IDisposable.Dispose() { this.Dispose(); } /// /// Checks whether this object is disposed. /// /// If the object has already been disposed. internal void CheckDisposed() { if (this.Disposed) { throw new ObjectDisposedException(this.GetType().Name); } } /// /// Releases unmanaged and - optionally - managed resources. /// /// true to release both managed and unmanaged resources; false to release only unmanaged resources. protected virtual void Dispose(bool disposing) { lock (this.isamSession) { if (!this.Disposed) { if (this.cleanup) { this.isamSession.RollbackTransaction(); this.cleanup = false; } this.Disposed = true; } } } } }