//-----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation.
//
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
using System.Globalization;
using Microsoft.Isam.Esent.Interop.Windows8;
///
/// A class that encapsulates a transaction on a JET_SESID.
///
public class Transaction : EsentResource
{
///
/// The underlying JET_SESID.
///
private readonly JET_SESID sesid;
///
/// Initializes a new instance of the Transaction class. This automatically
/// begins a transaction. The transaction will be rolled back if
/// not explicitly committed.
///
/// The session to start the transaction for.
public Transaction(JET_SESID sesid)
{
this.sesid = sesid;
this.Begin();
}
///
/// Gets the current transaction level of the
/// .
/// Requires Win10.
///
public int TransactionLevel
{
get
{
int transactionLevel = -1;
if (EsentVersion.SupportsWindows10Features)
{
Windows8Api.JetGetSessionParameter(
this.sesid,
Windows10.Windows10Sesparam.TransactionLevel,
out transactionLevel);
}
return transactionLevel;
}
}
///
/// Gets a value indicating whether this object is currently in a
/// transaction.
///
public bool IsInTransaction
{
get
{
this.CheckObjectIsNotDisposed();
return this.HasResource;
}
}
///
/// Returns a that represents the current .
///
///
/// A that represents the current .
///
public override string ToString()
{
return string.Format(CultureInfo.InvariantCulture, "Transaction (0x{0:x})", this.sesid.Value);
}
///
/// Begin a transaction. This object should not currently be
/// in a transaction.
///
public void Begin()
{
this.CheckObjectIsNotDisposed();
if (this.IsInTransaction)
{
throw new InvalidOperationException("Already in a transaction");
}
Api.JetBeginTransaction(this.sesid);
this.ResourceWasAllocated();
Debug.Assert(this.IsInTransaction, "Begin finished, but object isn't in a transaction");
}
///
/// Commit a transaction. This object should be in a transaction.
///
/// JetCommitTransaction options.
public void Commit(CommitTransactionGrbit grbit)
{
this.CheckObjectIsNotDisposed();
if (!this.IsInTransaction)
{
throw new InvalidOperationException("Not in a transaction");
}
Api.JetCommitTransaction(this.sesid, grbit);
this.ResourceWasReleased();
Debug.Assert(!this.IsInTransaction, "Commit finished, but object is still in a transaction");
}
///
/// Commit a transaction. This object should be in a transaction.
///
/// JetCommitTransaction options.
/// Duration for committing lazy transactions.
/// Commit-id for this commit record.
public void Commit(CommitTransactionGrbit grbit, TimeSpan durableCommit, out JET_COMMIT_ID commitId)
{
this.CheckObjectIsNotDisposed();
if (!this.IsInTransaction)
{
throw new InvalidOperationException("Not in a transaction");
}
Windows8.Windows8Api.JetCommitTransaction2(this.sesid, grbit, durableCommit, out commitId);
this.ResourceWasReleased();
Debug.Assert(!this.IsInTransaction, "Commit finished, but object is still in a transaction");
}
///
/// Rollback a transaction. This object should be in a transaction.
///
public void Rollback()
{
this.CheckObjectIsNotDisposed();
if (!this.IsInTransaction)
{
throw new InvalidOperationException("Not in a transaction");
}
Api.JetRollback(this.sesid, RollbackTransactionGrbit.None);
this.ResourceWasReleased();
Debug.Assert(!this.IsInTransaction, "Commit finished, but object is still in a transaction");
}
///
/// Called when the transaction is being disposed while active.
/// This should rollback the transaction.
///
protected override void ReleaseResource()
{
this.Rollback();
}
}
}