Transaction::Simple provides a generic way to add active
transactional support to objects. The transaction methods added by
this module will work with most objects, excluding those that cannot
be Marshaled (bindings, procedure objects, IO instances, or
singleton objects).

The transactions supported by Transaction::Simple are not backend
transaction; that is, they have nothing to do with any sort of data
store. They are "live" transactions occurring in memory and in the
object itself. This is to allow "test" changes to be made to an
object before making the changes permanent.

Transaction::Simple can handle an "infinite" number of transactional
levels (limited only by memory). If I open two transactions, commit
the first, but abort the second, the object will revert to the
original version.

Transaction::Simple is copyright ? 2003 by Austin Ziegler and is
licensed under an MIT-style licence.

Usage
-----
  include 'transaction/simple'

  v = "Hello, you."               # => "Hello, you."
  v.extend(Transaction::Simple)   # => "Hello, you."

  v.start_transaction             # => ... (a Marshal string)
  v.transaction_open?             # => true

  v.gsub!(/you/, "world")         # => "Hello, world."
  v.rewind_transaction            # => "Hello, you."
  v.transaction_open?             # => true

  v.gsub!(/you/, "HAL")           # => "Hello, HAL."
  v.abort_transaction             # => "Hello, you."
  v.transaction_open?             # => false

  v.start_transaction             # => ... (a Marshal string)
  v.start_transaction             # => ... (a Marshal string)
  v.transaction_open?             # => true

  v.gsub!(/you/, "HAL")           # => "Hello, HAL."
  v.commit_transaction            # => "Hello, HAL."
  v.transaction_open?             # => true

  v.abort_transaction             # => "Hello, you."
  v.transaction_open?             # => false

Contraindications
-----------------
While Transaction::Simple is very useful, it has some severe
limitations that must be understood. Transaction::Simple:

  * uses Marshal. Thus, any object which cannot be Marshal-ed cannot
    use Transaction::Simple.
  * does not manage resources. Resources external to the object and
    its instance variables are not managed at all. However, all
    instance variables and objects "belonging" to those instance
    variables are managed. If there are object reference counts to
    be handled, Transaction::Simple will probably cause problems.
  * is not thread-safe. In the ACID ("atomic, consistent, isolated,
    durable") test, Transaction::Simple provides ACD, but it is up
    to the user of Transaction::Simple to provide isolation.
    Transactions should be considered "critical sections" in
    multi-threaded applications.
  * does not maintain Object#__id__ values on rewind or abort. This
    may change for future versions that will be Ruby 1.8 or better
    only.

-austin
--
austin ziegler    * austin / halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.07.09
                                         * 12:48:17