/* * * Copyright (c) 2006 The Apache Software Foundation * * 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. * */ #ifndef _TxBuffer_ #define _TxBuffer_ #include #include #include #include #include /** * Represents a single transaction. As such, an instance of this class * will hold a list of operations representing the workload of the * transaction. This work can be committed or rolled back. Committing * is a two-stage process: first all the operations should be * prepared, then if that succeeds they can be committed. * * In the 2pc case, a successful prepare may be followed by either a * commit or a rollback. * * Atomicity of prepare is ensured by using a lower level * transactional facility. This saves explicitly rolling back all the * successfully prepared ops when one of them fails. i.e. we do not * use 2pc internally, we instead ensure that prepare is atomic at a * lower level. This makes individual prepare operations easier to * code. * * Transactions on a messaging broker effect three types of 'action': * (1) updates to persistent storage (2) updates to transient storage * or cached data (3) network writes. * * Of these, (1) should always occur atomically during prepare to * ensure that if the broker crashes while a transaction is being * completed the persistent state (which is all that then remains) is * consistent. (3) can only be done on commit, after a successful * prepare. There is a little more flexibility with (2) but any * changes made during prepare should be subject to the control of the * TransactionalStore in use. */ namespace qpid { namespace broker { class TxBuffer{ typedef std::vector::iterator op_iterator; std::vector ops; public: /** * Requests that all ops are prepared. This should * primarily involve making sure that a persistent record * of the operations is stored where necessary. * * All ops will be prepared under a transaction on the * specified store. If any operation fails on prepare, * this transaction will be rolled back. * * Once prepared, a transaction can be committed (or in * the 2pc case, rolled back). * * @returns true if all the operations prepared * successfully, false if not. */ bool prepare(TransactionalStore* const store); /** * Signals that the ops all prepared all completed * successfully and can now commit, i.e. the operation can * now be fully carried out. * * Should only be called after a call to prepare() returns * true. */ void commit(); /** * Rolls back all the operations. * * Should only be called either after a call to prepare() * returns true (2pc) or instead of a prepare call * ('server-local') */ void rollback(); /** * Adds an operation to the transaction. */ void enlist(TxOp* const op); }; } } #endif