FREE Subscription to Dr. Dobb’s Digest: Same Great Content, New Digital Edition
Site Archive (Complete)
Database
Email
Print
Reprint

add to:
Del.icio.us
Digg
Google
Furl
Slashdot
Y! MyWeb
Blink
November 06, 2007

Transactional Programming

(Page 5 of 7)

Implementation

The implementation of the Atomic Library is based around a central stack—a transaction stack—that logs each operation. Whenever an atomic container is modified, it pushes a record of the operation onto the stack.

Each operation is recorded in the struct:

struct Transaction { atomic::container* container; object_pointer node; enum { insertion, deletion } event; };

When a transaction is entered, the constructor of atomic::transaction stores the initial size of the transaction stack. When a transaction exits, the destructor of atomic::transaction can roll back all operations (in reverse order) to the initial size of the transaction stack. The transaction::commit() method sets a flag in the transaction telling it not to roll back.

There are just two types of atomic operations—insert and delete. Other operations can be composed of insertions or deletions.

All atomic containers derive from atomic::container:

class container { public: virtual ~container(); virtual void destroy(object_pointer)=0; virtual void unlink(object_pointer)=0; virtual void relink(object_pointer)=0; };

When an item is inserted into a container, it logs an insertion, a pointer to the container, and a pointer to the inserted object on the transaction stack.

When an item is deleted from a container, it logs a deletion, a pointer to the container, and a pointer to the deleted object on the transaction stack. The object is not destroyed at this point in case it needs to be inserted back into the container.

Rolling Back

Rolling back is performed differently on different containers. But what is extremely important is that rolling back must not fail. Fortunately, this turns out to be possible, even for tree-based containers such as atomic::set, atomic::map, atomic::multiset, and atomic::multimap.

When an insertion is rolled back, the unlink() function is called on the container to remove the item from the data structure, and destroy() is called to delete the object.

When a deletion is rolled back, the relink() function is called on the container to insert the item back into the data structure. The deleted item must contain a hint where the item should be inserted.

Previous Page | 1 Transactional Programming | 2 Transactions | 3 Nesting Transactions | 4 Transactional Values | 5 Implementation | 6 Lists and Trees | 7 Cleanup, Concurrent Access, Performance Next Page
TOP 5 ARTICLES
No Top Articles.



MICROSITES
FEATURED TOPIC

ADDITIONAL TOPICS

INFO-LINK