[SF 2580108] Improve transaction handling

This commit is contained in:
Aleksandar Fabijanic
2009-02-08 23:14:54 +00:00
parent ad543acb58
commit d11f007d23
41 changed files with 3484 additions and 2142 deletions

View File

@@ -7,7 +7,7 @@
// Package: Core
// Module: AutoTransaction
//
// Definition of the AutoTransaction class.
// Forward header for the Transaction class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
@@ -41,49 +41,14 @@
#define Data_AutoTransaction_INCLUDED
#include "Poco/Data/Data.h"
#include "Poco/Data/Session.h"
#include "Poco/Logger.h"
#include "Poco/Data/Transaction.h"
namespace Poco {
namespace Data {
class Data_API AutoTransaction
/// AutoTransaction helps with transactions in domain logic.
/// When an AutoTransaction object is created, it first checks whether a
/// transaction is in progress. If not, a new transaction is created.
/// When the AutoTransaction is destroyed, and commit() has been called,
/// nothing is done. Otherwise, the current transaction is rolled back.
{
public:
AutoTransaction(Poco::Data::Session& session, Poco::Logger* pLogger = 0);
/// Creates the AutoTransaction, using the given database session and logger.
~AutoTransaction();
/// Destroys the AutoTransaction.
/// Rolls back the current database transaction if it has not been commited
/// (by calling commit()), or rolled back (by calling rollback()).
///
/// If an exception is thrown during rollback, the exception is logged
/// and no further action is taken.
void commit();
/// Commits the current transaction.
void rollback();
/// Rolls back the current transaction.
private:
AutoTransaction();
AutoTransaction(const AutoTransaction&);
AutoTransaction& operator = (const AutoTransaction&);
Session& _session;
Logger* _pLogger;
bool _mustRollback;
};
typedef Transaction AutoTransaction;
} } // namespace Poco::Data

View File

@@ -72,7 +72,12 @@ public:
void rollback();
void close();
bool isConnected();
bool canTransact();
bool isTransaction();
void setTransactionIsolation(Poco::UInt32);
Poco::UInt32 getTransactionIsolation();
bool hasTransactionIsolation(Poco::UInt32);
bool isTransactionIsolation(Poco::UInt32);
const std::string& connectorName();
void setFeature(const std::string& name, bool state);
bool getFeature(const std::string& name);

View File

@@ -173,6 +173,11 @@ class Data_API Session
/// For complete list of supported data types with their respective specifications, see the documentation for format in Foundation.
{
public:
static const Poco::UInt32 TRANSACTION_READ_UNCOMMITTED = 0x00000001L;
static const Poco::UInt32 TRANSACTION_READ_COMMITTED = 0x00000002L;
static const Poco::UInt32 TRANSACTION_REPEATABLE_READ = 0x00000004L;
static const Poco::UInt32 TRANSACTION_SERIALIZABLE = 0x00000008L;
Session(Poco::AutoPtr<SessionImpl> ptrImpl);
/// Creates the Session.
@@ -221,9 +226,26 @@ public:
bool isConnected();
/// Returns true iff session is connected, false otherwise.
bool canTransact();
/// Returns true if session has transaction capabilities.
bool isTransaction();
/// Returns true iff a transaction is in progress, false otherwise.
void setTransactionIsolation(Poco::UInt32);
/// Sets the transaction isolation level.
Poco::UInt32 getTransactionIsolation();
/// Returns the transaction isolation level.
bool hasTransactionIsolation(Poco::UInt32 ti);
/// Returns true iff the transaction isolation level corresponding
/// to the supplied bitmask is supported.
bool isTransactionIsolation(Poco::UInt32 ti);
/// Returns true iff the transaction isolation level corresponds
/// to the supplied bitmask.
std::string uri();
/// Returns the URI for this session.
@@ -318,12 +340,42 @@ inline bool Session::isConnected()
}
inline bool Session::canTransact()
{
return _ptrImpl->canTransact();
}
inline bool Session::isTransaction()
{
return _ptrImpl->isTransaction();
}
inline void Session::setTransactionIsolation(Poco::UInt32 ti)
{
_ptrImpl->setTransactionIsolation(ti);
}
inline Poco::UInt32 Session::getTransactionIsolation()
{
return _ptrImpl->getTransactionIsolation();
}
inline bool Session::hasTransactionIsolation(Poco::UInt32 ti)
{
return _ptrImpl->hasTransactionIsolation(ti);
}
inline bool Session::isTransactionIsolation(Poco::UInt32 ti)
{
return _ptrImpl->isTransactionIsolation(ti);
}
inline std::string Session::uri(const std::string& connector,
const std::string& connectionString)
{

View File

@@ -83,9 +83,26 @@ public:
virtual bool isConnected() = 0;
/// Returns true if session is connected, false otherwise.
virtual bool canTransact() = 0;
/// Returns true if session has transaction capabilities.
virtual bool isTransaction() = 0;
/// Returns true iff a transaction is a transaction is in progress, false otherwise.
virtual void setTransactionIsolation(Poco::UInt32) = 0;
/// Sets the transaction isolation level.
virtual Poco::UInt32 getTransactionIsolation() = 0;
/// Returns the transaction isolation level.
virtual bool hasTransactionIsolation(Poco::UInt32) = 0;
/// Returns true iff the transaction isolation level corresponding
/// to the supplied bitmask is supported.
virtual bool isTransactionIsolation(Poco::UInt32) = 0;
/// Returns true iff the transaction isolation level corresponds
/// to the supplied bitmask.
virtual const std::string& connectorName() = 0;
/// Returns the name of the connector.

View File

@@ -0,0 +1,242 @@
//
// Transaction.h
//
// $Id: //poco/Main/Data/include/Poco/Data/Transaction.h#2 $
//
// Library: Data
// Package: Core
// Module: Transaction
//
// Definition of the Transaction class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
#ifndef Data_Transaction_INCLUDED
#define Data_Transaction_INCLUDED
#include "Poco/Data/Data.h"
#include "Poco/Data/Session.h"
#include "Poco/Logger.h"
namespace Poco {
namespace Data {
class Data_API Transaction
/// Transaction helps with transactions in domain logic.
/// When an Transaction object is created, it first checks whether a
/// transaction is in progress. If not, a new transaction is created.
/// When the Transaction is destroyed, and commit() has been called,
/// nothing is done. Otherwise, the current transaction is rolled back.
/// See Transaction for more detaisl nad purpose of this template.
{
public:
template <typename T>
class Transactor
/// Transactor is a helper functor template.
/// It is used to consolidate the C++ code that participates in
/// the transaction.
///
/// Example usage:
///
/// struct ATransaction
/// {
/// void operator () (Session& session) const
/// {
/// // do something ...
/// }
/// };
///
/// ATransaction t;
/// Transaction at(session, t); // commits, if successful
///
/// See Transaction for more details on how to use Transactor.
{
public:
Transactor(T& transactor): _transactor(transactor)
/// Creates the Transactor
{
}
inline void operator () (Poco::Data::Session& session)
{
_transactor(session);
}
inline void operator () (Poco::Data::Session& session) const
{
_transactor(session);
}
private:
Transactor();
Transactor(const Transactor&);
Transactor& operator = (const Transactor&);
T& _transactor;
};
Transaction(Poco::Data::Session& session, Poco::Logger* pLogger = 0);
/// Creates the Transaction and starts it, using the given database session and logger.
Transaction(Poco::Data::Session& session, bool start);
/// Creates the Transaction, using the given database session.
/// If start is true, transaction is started, otherwise begin() must be called
/// to start the transaction.
template <typename T>
Transaction(Poco::Data::Session& rSession, T& t, Poco::Logger* pLogger = 0):
_rSession(rSession),
_pLogger(pLogger)
/// Creates the Transaction, using the given database session and logger.
/// The type for the second argument must be Transactor-compatible, i.e.
/// provide the overload for the operator ().
/// When transaction is created using this constructor, it is executed and
/// commited automatically. If no error occurs, rollback is disabled and does
/// not occur at destruction time.
{
begin();
execute(t);
}
~Transaction();
/// Destroys the Transaction.
/// Rolls back the current database transaction if it has not been commited
/// (by calling commit()), or rolled back (by calling rollback()).
///
/// If an exception is thrown during rollback, the exception is logged
/// and no further action is taken.
void setIsolation(Poco::UInt32 ti);
/// Sets the transaction isolation level.
Poco::UInt32 getIsolation();
/// Returns the transaction isolation level.
bool hasIsolation(Poco::UInt32 ti);
/// Returns true iff the transaction isolation level corresponding
/// to the supplied bitmask is supported.
bool isIsolation(Poco::UInt32 ti);
/// Returns true iff the transaction isolation level corresponds
/// to the supplied bitmask.
void execute(const std::string& sql, bool doCommit = true);
/// Executes and, if doCommit is true, commits the transaction.
/// Passing true value for commit disables rollback during destruction
/// of this Transaction object.
void execute(const std::vector<std::string>& sql);
/// Executes all the SQL statements supplied in the vector and, after the last
/// one is sucesfully executed, commits the transaction.
/// If an error occurs during execution, transaction is rolled back.
/// Passing true value for commit disables rollback during destruction
/// of this Transaction object.
template <typename T>
void transact(T& t)
/// Executes the transactor and, if doCommit is true, commits the transaction.
/// Passing true value for commit disables rollback during destruction
/// of this Transaction object.
{
Transactor<T> transactor(t);
transactor(_rSession);
commit();
}
void commit();
/// Commits the current transaction.
void rollback();
/// Rolls back the current transaction.
bool isActive();
/// Returns false after the transaction has been committed or rolled back,
/// true if the transaction is ongoing.
void setLogger(Poco::Logger* pLogger);
/// Sets the logger for this transaction.
/// Transaction does not take the ownership of the pointer.
private:
Transaction();
Transaction(const Transaction&);
Transaction& operator = (const Transaction&);
void begin();
/// Begins the transaction if the session is already not in transaction.
/// Otherwise does nothing.
Session _rSession;
Logger* _pLogger;
};
inline bool Transaction::isActive()
{
return _rSession.isTransaction();
}
inline void Transaction::setIsolation(Poco::UInt32 ti)
{
_rSession.setTransactionIsolation(ti);
}
inline Poco::UInt32 Transaction::getIsolation()
{
return _rSession.getTransactionIsolation();
}
inline bool Transaction::hasIsolation(Poco::UInt32 ti)
{
return _rSession.isTransactionIsolation(ti);
}
inline bool Transaction::isIsolation(Poco::UInt32 ti)
{
return _rSession.isTransactionIsolation(ti);
}
inline void Transaction::setLogger(Poco::Logger* pLogger)
{
_pLogger = pLogger;
}
} } // namespace Poco::Data
#endif // Data_Transaction_INCLUDED