MessageQueueTransactionManager.cs :  » Inversion-of-Control-Dependency-Injection » Spring.net » Spring » Messaging » Core » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Inversion of Control Dependency Injection » Spring.net 
Spring.net » Spring » Messaging » Core » MessageQueueTransactionManager.cs
#region License

/*
 * Copyright 2002-2008 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#endregion


using System.Messaging;
using Common.Logging;
using Spring.Data.Core;
using Spring.Transaction;
using Spring.Transaction.Support;
using Spring.Util;

namespace Spring.Messaging.Core{
    /// <summary>
    /// <see cref="IPlatformTransactionManager"/> implementation for MSMQ.  Binds a 
    /// MessageQueueTransaction to the thread.
    /// </summary>
    /// <remarks>
    /// <para>
    /// This local strategy is an alternative to executing MSMQ operations within 
    /// DTC transactions. Its advantage is that multiple MSMQ operations can 
    /// easily participate within the same local MessagingTransaction transparently when
    /// using the <see cref="MessageQueueTemplate"/> class for send and recieve operations
    /// and not pay the overhead of a DTC transaction.  
    /// </para>
    /// <para>Transaction synchronization is turned off by default, as this manager might
    /// be used alongside a IDbProvider-based Spring transaction manager such as the
    /// ADO.NET <see cref="AdoPlatformTransactionManager"/>.
    /// which has stronger needs for synchronization.</para>
    /// </remarks>
    /// <author>Mark Pollack</author>
    public class MessageQueueTransactionManager : AbstractPlatformTransactionManager
    {
        /// <summary>
        /// Location where the message transaction is stored in thread local storage.
        /// </summary>
        public static readonly string CURRENT_TRANSACTION_SLOTNAME =
            UniqueKey.GetTypeScopedString(typeof (MessageQueueTransaction), "Current");

        #region Logging Definition

        private static readonly ILog LOG = LogManager.GetLogger(typeof (MessageQueueTransactionManager));

        #endregion

        /// <summary>
        /// Initializes a new instance of the <see cref="MessageQueueTransactionManager"/> class.
        /// </summary>
        /// <remarks>
        /// Turns off transaction synchronization by default, as this manager might
        /// be used alongside a DbProvider-based Spring transaction manager like
        /// AdoPlatformTransactionManager, which has stronger needs for synchronization.
        /// Only one manager is allowed to drive synchronization at any point of time.
        /// </remarks>
        public MessageQueueTransactionManager()
        {
            TransactionSynchronization = TransactionSynchronizationState.Never;
        }

        /// <summary>
        /// Return the current transaction object.
        /// </summary>
        /// <returns>The current transaction object.</returns>
        /// <exception cref="Spring.Transaction.CannotCreateTransactionException">
        /// If transaction support is not available.
        /// </exception>
        /// <exception cref="Spring.Transaction.TransactionException">
        /// In the case of lookup or system errors.
        /// </exception>
        protected override object DoGetTransaction()
        {
            MessageQueueTransactionObject txObject = new MessageQueueTransactionObject();
            txObject.ResourceHolder =
                (MessageQueueResourceHolder) TransactionSynchronizationManager.GetResource(CURRENT_TRANSACTION_SLOTNAME);
            return txObject;
        }

        /// <summary>
        /// Check if the given transaction object indicates an existing transaction
        /// (that is, a transaction which has already started).
        /// </summary>
        /// <param name="transaction">MessageQueueTransactionObject object returned by
        /// <see cref="Spring.Transaction.Support.AbstractPlatformTransactionManager.DoGetTransaction"/>.</param>
        /// <returns>
        /// True if there is an existing transaction.
        /// </returns>
        protected override bool IsExistingTransaction(object transaction)
        {
            MessageQueueTransactionObject txObject = (MessageQueueTransactionObject) transaction;
            return (txObject.ResourceHolder != null);
        }

        /// <summary>
        /// Begin a new transaction with the given transaction definition.
        /// </summary>
        /// <param name="transaction">Transaction object returned by
        /// <see cref="Spring.Transaction.Support.AbstractPlatformTransactionManager.DoGetTransaction"/>.</param>
        /// <param name="definition"><see cref="Spring.Transaction.ITransactionDefinition"/> instance, describing
        /// propagation behavior, isolation level, timeout etc.</param>
        /// <exception cref="Spring.Transaction.TransactionException">
        /// In the case of creation or system errors.
        /// </exception>
        protected override void DoBegin(object transaction, ITransactionDefinition definition)
        {
            MessageQueueTransactionObject txObject = (MessageQueueTransactionObject) transaction;

            MessageQueueTransaction mqt = new MessageQueueTransaction();
            mqt.Begin();

            txObject.ResourceHolder = new MessageQueueResourceHolder(mqt);
            txObject.ResourceHolder.SynchronizedWithTransaction = true;

            int timeout = DetermineTimeout(definition);
            if (timeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT)
            {
                txObject.ResourceHolder.TimeoutInSeconds = timeout;
            }
            TransactionSynchronizationManager.BindResource(CURRENT_TRANSACTION_SLOTNAME, txObject.ResourceHolder);
        }

        /// <summary>
        /// Suspend the resources of the current transaction.
        /// </summary>
        /// <param name="transaction">Transaction object returned by
        /// <see cref="Spring.Transaction.Support.AbstractPlatformTransactionManager.DoGetTransaction"/>.</param>
        /// <returns>
        /// An object that holds suspended resources (will be kept unexamined for passing it into
        /// <see cref="Spring.Transaction.Support.AbstractPlatformTransactionManager.DoResume"/>.)
        /// </returns>
        protected override object DoSuspend(object transaction)
        {
            MessageQueueTransactionObject txObject = (MessageQueueTransactionObject) transaction;
            txObject.ResourceHolder = null;
            return TransactionSynchronizationManager.UnbindResource(CURRENT_TRANSACTION_SLOTNAME);
        }

        /// <summary>
        /// Resume the resources of the current transaction.
        /// </summary>
        /// <param name="transaction">Transaction object returned by
        /// <see cref="Spring.Transaction.Support.AbstractPlatformTransactionManager.DoGetTransaction"/>.</param>
        /// <param name="suspendedResources">The object that holds suspended resources as returned by
        /// <see cref="Spring.Transaction.Support.AbstractPlatformTransactionManager.DoSuspend"/>.</param>
        protected override void DoResume(object transaction, object suspendedResources)
        {
            MessageQueueResourceHolder queueHolder = (MessageQueueResourceHolder) suspendedResources;
            TransactionSynchronizationManager.BindResource(CURRENT_TRANSACTION_SLOTNAME, queueHolder);
        }

        /// <summary>
        /// Perform an actual commit on the given transaction.
        /// </summary>
        /// <param name="status">The status representation of the transaction.</param>
        /// <remarks>
        ///   <p>
        /// An implementation does not need to check the rollback-only flag.
        /// </p>
        /// </remarks>
        protected override void DoCommit(DefaultTransactionStatus status)
        {
            MessageQueueTransactionObject txObject = (MessageQueueTransactionObject) status.Transaction;
            MessageQueueTransaction transaction = txObject.ResourceHolder.MessageQueueTransaction;
            try
            {
                if (LOG.IsDebugEnabled)
                {
                    LOG.Debug("Committing MessageQueueTransaction");
                }
                transaction.Commit();
            }
            catch (MessageQueueException ex)
            {
                throw new TransactionSystemException("Could not commit DefaultMessageQueue transaction", ex);
            }
        }

        /// <summary>
        /// Perform an actual rollback on the given transaction, calls Transaction.Abort().
        /// </summary>
        /// <param name="status">The status representation of the transaction.</param>
        /// <remarks>
        /// An implementation does not need to check the new transaction flag.
        /// </remarks>
        protected override void DoRollback(DefaultTransactionStatus status)
        {
            MessageQueueTransactionObject txObject = (MessageQueueTransactionObject) status.Transaction;
            MessageQueueTransaction transaction = txObject.ResourceHolder.MessageQueueTransaction;
            try
            {
                if (LOG.IsDebugEnabled)
                {
                    LOG.Debug("Committing MessageQueueTransaction");
                }
                transaction.Abort();
            }
            catch (MessageQueueException ex)
            {
                throw new TransactionSystemException("Could not roll back DefaultMessageQueue transaction", ex);
            }
        }

        /// <summary>
        /// Set the given transaction rollback-only. Only called on rollback
        /// if the current transaction takes part in an existing one.
        /// </summary>
        /// <param name="status">The status representation of the transaction.</param>
        /// <remarks>Default implementation throws an IllegalTransactionStateException,
        /// assuming that participating in existing transactions is generally not
        /// supported. Subclasses are of course encouraged to provide such support.
        /// </remarks>
        /// <exception cref="Spring.Transaction.TransactionException">
        /// In the case of system errors.
        /// </exception>
        protected override void DoSetRollbackOnly(DefaultTransactionStatus status)
        {
            MessageQueueTransactionObject txObject = (MessageQueueTransactionObject) status.Transaction;
            txObject.ResourceHolder.RollbackOnly = true;
        }

        /// <summary>
        /// Cleanup resources after transaction completion.
        /// </summary>
        /// <param name="transaction">Transaction object returned by
        /// <see cref="Spring.Transaction.Support.AbstractPlatformTransactionManager.DoGetTransaction"/>.</param>
        /// <remarks>
        /// <para>
        /// Called after <see cref="Spring.Transaction.Support.AbstractPlatformTransactionManager.DoCommit"/>
        /// and
        /// <see cref="Spring.Transaction.Support.AbstractPlatformTransactionManager.DoRollback"/>
        /// execution on any outcome.
        /// </para>
        /// </remarks>
        protected override void DoCleanupAfterCompletion(object transaction)
        {
            MessageQueueTransactionObject txObject = (MessageQueueTransactionObject) transaction;
            TransactionSynchronizationManager.UnbindResource(CURRENT_TRANSACTION_SLOTNAME);
            txObject.ResourceHolder.Clear();
        }


        private class MessageQueueTransactionObject : ISmartTransactionObject
        {
            private MessageQueueResourceHolder resourceHolder;


            public MessageQueueResourceHolder ResourceHolder
            {
                get { return resourceHolder; }
                set { resourceHolder = value; }
            }

            #region ISmartTransactionObject Members

            public bool RollbackOnly
            {
                get { return resourceHolder.RollbackOnly; }
            }

            #endregion
        }
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.