mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-29 12:18:01 +01:00
[SF 2580108] Improve transaction handling
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
242
Data/include/Poco/Data/Transaction.h
Normal file
242
Data/include/Poco/Data/Transaction.h
Normal 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
|
||||
Reference in New Issue
Block a user