blob: c289ef795a9ba47f8c7d36ff250a279c2228c177 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
#ifndef _ACTIVEMQ_CORE_ACTIVEMQTRANSACTIONCONTEXT_H_
#define _ACTIVEMQ_CORE_ACTIVEMQTRANSACTIONCONTEXT_H_
#include <memory>
#include <cms/Message.h>
#include <cms/XAResource.h>
#include <cms/CMSException.h>
#include <cms/XAException.h>
#include <activemq/util/Config.h>
#include <activemq/exceptions/ActiveMQException.h>
#include <activemq/commands/LocalTransactionId.h>
#include <activemq/core/Synchronization.h>
#include <activemq/util/LongSequenceGenerator.h>
#include <decaf/lang/exceptions/InvalidStateException.h>
#include <decaf/util/StlSet.h>
#include <decaf/util/Properties.h>
#include <decaf/util/concurrent/Mutex.h>
namespace activemq {
namespace core {
namespace kernels {
class ActiveMQSessionKernel;
}
using decaf::lang::Pointer;
class LocalTransactionEventListener;
class ActiveMQConnection;
class TxContextData;
/**
* Transaction Management class, hold messages that are to be redelivered
* upon a request to roll-back. The Transaction represents an always
* running transaction, when it is committed or rolled back it silently
* creates a new transaction for the next set of messages. The only
* way to permanently end this transaction is to delete it.
*
* @since 2.0
*/
class AMQCPP_API ActiveMQTransactionContext : public cms::XAResource {
private:
// Internal structure to hold all class TX data.
TxContextData* context;
// Session this Transaction is associated with
activemq::core::kernels::ActiveMQSessionKernel* session;
// The Connection that is the parent of the Session.
ActiveMQConnection* connection;
// List of Registered Synchronizations
decaf::util::StlSet< Pointer<Synchronization> > synchronizations;
private:
ActiveMQTransactionContext(const ActiveMQTransactionContext&);
ActiveMQTransactionContext& operator=(const ActiveMQTransactionContext&);
public:
/**
* Constructor
*
* @param session
* The session that contains this transaction
* @param properties
* Configuration parameters for this object
*/
ActiveMQTransactionContext(activemq::core::kernels::ActiveMQSessionKernel* session,
const decaf::util::Properties& properties);
virtual ~ActiveMQTransactionContext();
/**
* Adds a Synchronization to this Transaction.
* @param sync - The Synchronization instance to add.
*/
virtual void addSynchronization(const Pointer<Synchronization>& sync);
/**
* Removes a Synchronization to this Transaction.
* @param sync - The Synchronization instance to add.
*/
virtual void removeSynchronization(const Pointer<Synchronization>& sync);
/**
* Begins a new transaction if one is not currently in progress.
* @throw ActiveMQException
*/
virtual void begin();
/**
* Commit the current Transaction
* @throw ActiveMQException
*/
virtual void commit();
/**
* Rollback the current Transaction
* @throw ActiveMQException
*/
virtual void rollback();
/**
* Get the Transaction Id object for the current
* Transaction, returns NULL if no transaction is running
* @return TransactionInfo
* @throw InvalidStateException if a Transaction is not in progress.
*/
virtual const decaf::lang::Pointer<commands::TransactionId>& getTransactionId() const;
/**
* Checks to see if there is currently a Transaction in progress returns
* false if not, true otherwise.
*
* @return true if a transaction is in progress.
*/
virtual bool isInTransaction() const;
/**
* Checks to see if there is currently an Local Transaction in progess, returns
* false if not, true otherwise.
*
* @return true if an Local Transaction is in progress.
*/
virtual bool isInLocalTransaction() const;
/**
* Checks to see if there is currently an XA Transaction in progress, returns
* false if not, true otherwise.
*
* @return true if an XA Transaction is in progress.
*/
virtual bool isInXATransaction() const;
public: // XAResource implementation.
virtual void commit(const cms::Xid* xid, bool onePhase);
virtual void end(const cms::Xid* xid, int flags);
virtual void forget(const cms::Xid* xid);
virtual int getTransactionTimeout() const;
virtual bool isSameRM(const cms::XAResource* theXAResource);
virtual int prepare(const cms::Xid* xid);
virtual int recover(int flag, cms::Xid** recovered);
virtual void rollback(const cms::Xid* xid);
virtual bool setTransactionTimeout(int seconds);
virtual void start(const cms::Xid* xid, int flags);
private:
std::string getResourceManagerId() const;
void setXid(const cms::Xid* xid);
bool equals(const cms::Xid* local, const cms::Xid* remote);
cms::XAException toXAException(cms::CMSException& ex);
cms::XAException toXAException(decaf::lang::Exception& ex);
void beforeEnd();
void afterCommit();
void afterRollback();
};
}}
#endif /*_ACTIVEMQ_CORE_ACTIVEMQTRANSACTIONCONTEXT_H_*/