/// <summary> /// Determine if the container should create its own /// MessageQueueTransaction when a IResourceTransactionManager is specified. /// Set the transaction name to the name of the spring object. /// Call base class Initialize() funtionality /// </summary> public override void Initialize() { //using non-DTC based transaction manager? bool isRtm = PlatformTransactionManager is IResourceTransactionManager; //using MessageQueueTransactionManager? bool isQtm = PlatformTransactionManager is MessageQueueTransactionManager; if (!isRtm && !isQtm) { throw new ArgumentException("Can not use the provied IPlatformTransactionManager of type " + PlatformTransactionManager.GetType() + ". It must implement IResourceTransactionManager or be a MessageQueueTransactionManager."); } //Set useContainerManagedMessageQueueTransaction = true when using // 1. non-DTC based transaction manager // 2. not the MessageQueueTransactionManager. if (!useMessageQueueTransactionManagerCalled && isRtm && !isQtm) { useContainerManagedMessageQueueTransaction = true; } // Use object name as default transaction name. if (TransactionDefinition.Name == null) { TransactionDefinition.Name = ObjectName; } // Proceed with superclass initialization. base.Initialize(); }
/// <summary> /// Rollback the transaction on exception. /// </summary> /// <param name="status">The transactional status.</param> /// <param name="ex">The exception.</param> protected void RollbackOnException(ITransactionStatus status, Exception ex) { LOG.Debug("Initiating transaction rollback on listener exception", ex); try { PlatformTransactionManager.Rollback(status); } catch (Exception ex2) { LOG.Error("Listener exception overridden by rollback error", ex2); throw; } }
/// <summary> /// Subclasses perform a receive opertion on the message queue and execute the /// message listener /// </summary> /// <param name="mq">The DefaultMessageQueue.</param> /// <returns> /// true if received a message, false otherwise /// </returns> protected override bool DoReceiveAndExecute(MessageQueue mq) { bool messageReceived = false; // Execute receive within transaction. ITransactionStatus status = PlatformTransactionManager.GetTransaction(TransactionDefinition); try { messageReceived = DoReceiveAndExecuteUsingPlatformTransactionManager(mq, status); } catch (Exception ex) { RollbackOnException(status, ex); Thread.Sleep(RecoveryTimeSpan); throw; } //if status has indicated rollback only, will rollback. PlatformTransactionManager.Commit(status); return(messageReceived); }