123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- //------------------------------------------------------------------------------
- // <copyright file="MessageQueueTransaction.cs" company="Microsoft">
- // Copyright (c) Microsoft Corporation. All rights reserved.
- // </copyright>
- //------------------------------------------------------------------------------
- using Experimental.System.Messaging.Interop;
- using System;
- using System.Threading;
- namespace Experimental.System.Messaging
- {
- /// <include file='doc\MessageQueueTransaction.uex' path='docs/doc[@for="MessageQueueTransaction"]/*' />
- /// <devdoc>
- /// <para>[To be supplied.]</para>
- /// </devdoc>
- public class MessageQueueTransaction : IDisposable
- {
- private ITransaction internalTransaction;
- private MessageQueueTransactionStatus transactionStatus;
- private bool disposed;
- /// <include file='doc\MessageQueueTransaction.uex' path='docs/doc[@for="MessageQueueTransaction.MessageQueueTransaction"]/*' />
- /// <devdoc>
- /// <para>
- /// Creates a new Message Queuing internal transaction context.
- /// </para>
- /// </devdoc>
- public MessageQueueTransaction()
- {
- this.transactionStatus = MessageQueueTransactionStatus.Initialized;
- }
- internal ITransaction InnerTransaction
- {
- get
- {
- return this.internalTransaction;
- }
- }
- /// <include file='doc\MessageQueueTransaction.uex' path='docs/doc[@for="MessageQueueTransaction.Status"]/*' />
- /// <devdoc>
- /// <para>
- /// The status of the transaction that this object represents.
- /// </para>
- /// </devdoc>
- public MessageQueueTransactionStatus Status
- {
- get
- {
- return this.transactionStatus;
- }
- }
- /// <include file='doc\MessageQueueTransaction.uex' path='docs/doc[@for="MessageQueueTransaction.Abort"]/*' />
- /// <devdoc>
- /// <para>
- /// Rolls back the pending internal transaction.
- /// </para>
- /// </devdoc>
- public void Abort()
- {
- lock (this)
- {
- if (this.internalTransaction == null)
- throw new InvalidOperationException(Res.GetString(Res.TransactionNotStarted));
- else
- {
- this.AbortInternalTransaction();
- }
- }
- }
- /// <include file='doc\MessageQueueTransaction.uex' path='docs/doc[@for="MessageQueueTransaction.AbortInternalTransaction"]/*' />
- /// <internalonly/>
- private void AbortInternalTransaction()
- {
- int status = this.internalTransaction.Abort(0, 0, 0);
- if (MessageQueue.IsFatalError(status))
- throw new MessageQueueException(status);
- this.internalTransaction = null;
- this.transactionStatus = MessageQueueTransactionStatus.Aborted;
- }
- /// <include file='doc\MessageQueueTransaction.uex' path='docs/doc[@for="MessageQueueTransaction.Begin"]/*' />
- /// <devdoc>
- /// <para>
- /// Begins a new Message Queuing internal transaction context.
- /// </para>
- /// </devdoc>
- public void Begin()
- {
- //Won't allow begining a new transaction after the object has been disposed.
- if (this.disposed)
- throw new ObjectDisposedException(GetType().Name);
- lock (this)
- {
- if (internalTransaction != null)
- throw new InvalidOperationException(Res.GetString(Res.TransactionStarted));
- else
- {
- int status = SafeNativeMethods.MQBeginTransaction(out this.internalTransaction);
- if (MessageQueue.IsFatalError(status))
- {
- this.internalTransaction = null;
- throw new MessageQueueException(status);
- }
- this.transactionStatus = MessageQueueTransactionStatus.Pending;
- }
- }
- }
- /// <include file='doc\MessageQueueTransaction.uex' path='docs/doc[@for="MessageQueueTransaction.BeginQueueOperation"]/*' />
- /// <internalonly/>
- internal ITransaction BeginQueueOperation()
- {
- #pragma warning disable 0618
- //@
- Monitor.Enter(this);
- #pragma warning restore 0618
- return this.internalTransaction;
- }
- /// <include file='doc\MessageQueueTransaction.uex' path='docs/doc[@for="MessageQueueTransaction.Commit"]/*' />
- /// <devdoc>
- /// <para>
- /// Commits a pending internal transaction.
- /// </para>
- /// </devdoc>
- public void Commit()
- {
- lock (this)
- {
- if (this.internalTransaction == null)
- throw new InvalidOperationException(Res.GetString(Res.TransactionNotStarted));
- else
- {
- int status = this.internalTransaction.Commit(0, 0, 0);
- if (MessageQueue.IsFatalError(status))
- throw new MessageQueueException(status);
- this.internalTransaction = null;
- this.transactionStatus = MessageQueueTransactionStatus.Committed;
- }
- }
- }
- /// <include file='doc\MessageQueueTransaction.uex' path='docs/doc[@for="MessageQueueTransaction.Dispose"]/*' />
- /// <devdoc>
- /// <para>
- /// Disposes this transaction instance, if it is in a
- /// pending status, the transaction will be aborted.
- /// </para>
- /// </devdoc>
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- /// <include file='doc\MessageQueueTransaction.uex' path='docs/doc[@for="MessageQueueTransaction.Dispose1"]/*' />
- /// <devdoc>
- /// <para>
- /// </para>
- /// </devdoc>
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- lock (this)
- {
- if (internalTransaction != null)
- this.AbortInternalTransaction();
- }
- }
- this.disposed = true;
- }
- /// <include file='doc\MessageQueueTransaction.uex' path='docs/doc[@for="MessageQueueTransaction.Finalize"]/*' />
- /// <internalonly/>
- ~MessageQueueTransaction()
- {
- Dispose(false);
- }
- /// <include file='doc\MessageQueueTransaction.uex' path='docs/doc[@for="MessageQueueTransaction.EndQueueOperation"]/*' />
- /// <internalonly/>
- internal void EndQueueOperation()
- {
- Monitor.Exit(this);
- }
- }
- }
|