PMDK C++ bindings  1.12.1-rc1
This is the C++ bindings documentation for PMDK's libpmemobj.
Public Types | Public Member Functions | Static Public Member Functions | List of all members
pmem::obj::basic_transaction Class Reference

C++ transaction handler class. More...

#include <libpmemobj++/transaction.hpp>

Inheritance diagram for pmem::obj::basic_transaction:
pmem::detail::transaction_base< false >

Public Types

using manual = typename detail::transaction_base< false >::manual
 C++ manual scope transaction class. More...
 
using automatic = typename detail::transaction_base< false >::automatic
 C++ automatic scope transaction class. More...
 
- Public Types inherited from pmem::detail::transaction_base< false >
enum  stage
 Possible stages of a transaction, for every stage one or more callbacks can be registered.
 

Public Member Functions

 ~basic_transaction () noexcept=delete
 Default destructor.
 
- Public Member Functions inherited from pmem::detail::transaction_base< false >
 ~transaction_base () noexcept=delete
 Default destructor. More...
 

Static Public Member Functions

template<typename... Locks>
static void run (obj::pool_base &pool, std::function< void()> tx, Locks &... locks)
 Execute a closure-like transaction and lock locks. More...
 
- Static Public Member Functions inherited from pmem::detail::transaction_base< false >
static void abort (int err)
 Manually abort the current transaction. More...
 
static void commit ()
 Manually commit a transaction. More...
 
static void run (obj::pool_base &pool, std::function< void()> tx, Locks &... locks)
 Execute a closure-like transaction and lock locks. More...
 
static void snapshot (const T *addr, size_t num=1)
 Takes a “snapshot” of given elements of type T number (1 by default), located at the given address ptr in the virtual memory space and saves it to the undo log. More...
 
static void register_callback (stage stg, std::function< void()> cb)
 Registers callback to be called on specified stage for the transaction. More...
 

Detailed Description

C++ transaction handler class.

This class should be used with care. It's recommended to use pmem::obj::flat_transaction instead.

This class is the pmemobj transaction handler. Scoped transactions are handled through two internal classes: manual and automatic.

This class also exposes a closure-like transaction API, which is the preferred way of handling transactions.

This API should NOT be mixed with C transactions API. One issue is that C++ callbacks registered using transaction::register_callback() would not be called if C++ transaction is created inside C transaction. The same is true if user calls pmemobj_tx_set_user_data() inside a C++ transaction.

The typical usage example would be:

using namespace pmem::obj;
void
general_tx_example()
{
/* pool root structure */
struct root {
mutex pmutex;
shared_mutex shared_pmutex;
p<int> count;
persistent_ptr<root> another_root;
};
/* create a pmemobj pool */
auto pop = pool<root>::create("poolfile", "layout", PMEMOBJ_MIN_POOL);
auto proot = pop.root();
/* typical usage schemes */
try {
/* take locks and start a transaction */
pop,
[&]() {
/* atomically allocate objects */
proot->another_root = make_persistent<root>();
/* atomically modify objects */
proot->count++;
},
proot->pmutex, proot->shared_pmutex);
/* a transaction error occurred, transaction got aborted
* reacquire locks if necessary */
} catch (...) {
/* some other exception got propagated from within the tx
* reacquire locks if necessary */
}
}

Member Typedef Documentation

◆ automatic

C++ automatic scope transaction class.

This class is one of pmemobj transaction handlers. All operations between creating and destroying the transaction object are treated as performed in a transaction block and can be rolled back. If you have a C++17 compliant compiler, the automatic transaction will commit and abort automatically depending on the context of object destruction.

The locks are held for the entire duration of the transaction. They are released at the end of the scope, so within the catch block, they are already unlocked. If the cleanup action requires access to data within a critical section, the locks have to be manually acquired once again.

The typical usage example would be:

using namespace pmem::obj;
int
automatic_tx_example()
{
/* pool root structure */
struct root {
mutex pmutex;
shared_mutex shared_pmutex;
p<int> count;
persistent_ptr<root> another_root;
};
/* create a pmemobj pool */
auto pop = pool<root>::create("poolfile", "layout", PMEMOBJ_MIN_POOL);
auto proot = pop.root();
try {
transaction::automatic tx(pop, proot->pmutex,
proot->shared_pmutex);
/* atomically allocate objects */
proot->another_root = make_persistent<root>();
/* atomically modify objects */
proot->count++;
/* manual transaction commit is no longer necessary */
/* an internal transaction error occurred, tx aborted
* reacquire locks if necessary */
} catch (...) {
/* some other exception thrown, tx aborted
* reacquire locks if necessary */
}
/* In complex cases with library calls, remember to check the status of
* the previous transaction. */
return transaction::error();
}

◆ manual

C++ manual scope transaction class.

This class is one of pmemobj transaction handlers. All operations between creating and destroying the transaction object are treated as performed in a transaction block and can be rolled back. The manual transaction has to be committed explicitly otherwise it will abort.

The locks are held for the entire duration of the transaction. They are released at the end of the scope, so within the catch block, they are already unlocked. If the cleanup action requires access to data within a critical section, the locks have to be manually acquired once again.

The typical usage example would be:

using namespace pmem::obj;
int
manual_tx_example()
{
/* pool root structure */
struct root {
mutex pmutex;
shared_mutex shared_pmutex;
p<int> count;
persistent_ptr<root> another_root;
};
/* create a pmemobj pool */
auto pop = pool<root>::create("poolfile", "layout", PMEMOBJ_MIN_POOL);
auto proot = pop.root();
try {
transaction::manual tx(pop, proot->pmutex,
proot->shared_pmutex);
/* atomically allocate objects */
proot->another_root = make_persistent<root>();
/* atomically modify objects */
proot->count++;
/* It's necessary to commit the transaction manually and
* it has to be the last operation in the transaction. */
/* an internal transaction error occurred, tx aborted
* reacquire locks if necessary */
} catch (...) {
/* some other exception thrown, tx aborted
* reacquire locks if necessary */
}
/* In complex cases with library calls, remember to check the status of
* the previous transaction. */
return transaction::error();
}

Member Function Documentation

◆ run()

template<typename... Locks>
static void pmem::obj::basic_transaction::run ( obj::pool_base pool,
std::function< void()>  tx,
Locks &...  locks 
)
inlinestatic

Execute a closure-like transaction and lock locks.

The locks have to be persistent memory resident locks. An attempt to lock the locks will be made. If any of the specified locks is already locked, the method will block. The locks are held until the end of the transaction. The transaction does not have to be committed manually. Manual aborts will end the transaction with an active exception.

If an exception is thrown within the transaction, it gets aborted and the exception is rethrown. Therefore extra care has to be taken with proper error handling.

The locks are held for the entire duration of the transaction. They are released at the end of the scope, so within the catch block, they are already unlocked. If the cleanup action requires access to data within a critical section, the locks have to be manually acquired once again.

Parameters
[in,out]poolthe pool in which the transaction will take place.
[in]txan std::function<void ()> which will perform operations within this transaction.
[in,out]lockslocks to be taken for the duration of the transaction.
Exceptions
transaction_erroron any error pertaining the execution of the transaction.
manual_tx_aborton manual transaction abort.

The documentation for this class was generated from the following file:
pmem::obj::mutex
Persistent memory resident mutex implementation.
Definition: mutex.hpp:31
pmem::obj::pool::create
static pool< T > create(const std::string &path, const std::string &layout, std::size_t size=PMEMOBJ_MIN_POOL, mode_t mode=DEFAULT_MODE)
Creates a new transactional object store pool.
Definition: pool.hpp:677
pmem::transaction_error
Custom transaction error class.
Definition: pexceptions.hpp:65
pmem::obj::basic_transaction::run
static void run(obj::pool_base &pool, std::function< void()> tx, Locks &... locks)
Execute a closure-like transaction and lock locks.
Definition: transaction.hpp:688
pmem::obj::p
Resides on pmem class.
Definition: p.hpp:35
pmem::obj::pool::root
persistent_ptr< T > root()
Retrieves pool's root object.
Definition: pool.hpp:627
pool.hpp
C++ pmemobj pool.
make_persistent.hpp
Persistent_ptr transactional allocation functions for objects.
pmem::obj
Main libpmemobj namespace.
Definition: allocation_flag.hpp:18
transaction.hpp
C++ pmemobj transactions.
pmem::obj::persistent_ptr
Persistent pointer class.
Definition: persistent_ptr.hpp:152
shared_mutex.hpp
Pmem-resident shared mutex.
pmem::detail::transaction_base< false >::commit
static void commit()
Manually commit a transaction.
Definition: transaction.hpp:325
pmem::obj::basic_transaction::manual
typename detail::transaction_base< false >::manual manual
C++ manual scope transaction class.
Definition: transaction.hpp:627
pext.hpp
Convenience extensions for the resides on pmem property template.
pmem::obj::basic_transaction::automatic
typename detail::transaction_base< false >::automatic automatic
C++ automatic scope transaction class.
Definition: transaction.hpp:653
persistent_ptr.hpp
Persistent smart pointer.
pmem::obj::shared_mutex
Persistent memory resident shared_mutex implementation.
Definition: shared_mutex.hpp:30
mutex.hpp
Pmem-resident mutex.