Transaction handling in C++One of the many features C++ added to C is surely the exception
handling. In the current litirature on the subject this new method
for signaling exceptional conditions or errors is described as much
cleaner, stable and compact than systematic use of return codes as
success/error communication.
Without repeating in the detail all problems inherent to exception
handling(1) I want to remark only the main idea: the complex part isn't where the
exception is generated (throw) or where the exception is handled (catch)
but in the methods of all classes the exception passes through almost
asynchronously during the stack unwinding process.
Paying some attention on how methods are written is relatively easy
avoid losing resources in case of exceptions (use of auto_ptr and
similar classes) but things are much more complex when one takes in
account the logical state of the object or other objects manipulated
before the throw. In the most strict meaning of exception-safe a method
should either succeed or being a no-op: in other words the logical
state of the object called (and other involved objects) should be the
same if an exception is thrown: no difference should be visible
through the public interface of all involved classes.
What is desirable is indeed quite similar to the transaction concept of
relational DBMS.
Starting from this base point I implemented a transaction handling in
C++ that considerably simplifies using exceptions as an error signaling
method.
Implementing commit/rollback in C++For a production management program I'm currently working on I'm
implementing a transactional server written in C++ that keeps
a memory representation of all production informations (available
quantities, orders, product composition, production phases, production
plans, customers, suppliers and the like).
The server exposes a list of logical transactions and the clients
require them using forms properly filled and sent using a tcp/ip
network connection.
All data is kept in a net data structure and the logical transactions
are C++ objects that manipulate/traverse the data and send the client
the requested results. If during the execution of a logical transaction
there is a logical error then an exception is thrown and the server
informs the client about the problems found processing the request.
All production data is kept in "stupid" classes, meaning that the only
methods those classes export are intherent the data structure
itself(2) . Using another wording the logical transaction manipulate objects
that are very similar to records of classical (non-OO) databases
and the only involved operations are read/assignment of fields or
pointers.
What I did was substituting the data fields with "intelligent" objects
that are able to record all assignments in a log to make possible a
recover (rollback). When implementing this the template concept of C++
has been very helpful.
(1) | For an extensive description read the article
"Exception Handling: A False Sense of Security" by Tom Cargill
available
online or the interesting collection of problems/solutions that that article
generated on USENET available on the book "Exceptional C++" by Herb
Sutter ISBN=0-201-61562-2.
|
(2) | I'm not currently a supporter of true object-oriented approaches to
this kind of business problems. In my opinion in something like
a production system there is a very strong central coordination
of many units with no local decision power. Distributing the
analysis of a process on all the involved classes doesn't simplify
the analysis itself. In other words the strong coupling present
in this domain make a pure OO approach a pointless effort.
|