views:

122

answers:

5

Hi,

How I can imitate transactions on objects. For example, I want to delete the item from one collection and then add the same item to other collection as an atomic action. It is possible to do a lot of checks when something failed and to roll back everything but this is annoying. Is there any technique (no difference what language (Java/C++/C#)) to achive this.

A: 

Yes, Memento pattern http://en.wikipedia.org/wiki/Memento_pattern

epitka
A: 

Software transactional memory is one approach. There is no language-agnostic technology for this that I know of.

Stephen Cleary
I saw only 866 downloads. Is it mature for production ?
Sorry; I noticed that it was an older project after I posted. The comment has been updated to refer to the Wikipedia entry, which covers some of the underlying concepts. This is an area in Computer Science that is currently being developed.
Stephen Cleary
A: 

You can use Herb Sutters' method

Like

   class EmployeeDatabase
    {
        public void TerminateEmployee(int index) 
        {
            // Clone sensitive objects.
            ArrayList tempActiveEmployees =
            (ArrayList) activeEmployees.Clone();
            ArrayList tempTerminatedEmployees =
            (ArrayList) terminatedEmployees.Clone();

            // Perform actions on temp objects.
            object employee = tempActiveEmployees[index];
            tempActiveEmployees.RemoveAt( index );
            tempTerminatedEmployees.Add( employee );

            // Now commit the changes.
            ArrayList tempSpace = null;

            ListSwap( ref activeEmployees,
                ref tempActiveEmployees,
                ref tempSpace );

            ListSwap( ref terminatedEmployees,
                ref tempTerminatedEmployees,
                ref tempSpace );
        }

        void ListSwap(ref ArrayList first,
            ref ArrayList second,
            ref ArrayList temp)
        {
            temp = first;
            first = second;
            second = temp;
            temp = null;
        }

        private ArrayList activeEmployees;
        private ArrayList terminatedEmployees;
}

Mainly it means to divide the code into 2 parts :

void ExceptionNeutralMethod()
    {
        //——————————
        // All code that could possibly throw exceptions is in this
        // first section. In this section, no changes in state are
        // applied to any objects in the system including this.
        //——————————


        //——————————
        // All changes are committed at this point using operations
        // strictly guaranteed not to throw exceptions.
        //——————————
    }

Of course it is just to show method I mean concerning ArrayList :). Better to use generics if possible, etc...

EDIT

Additionally if you have extreme requirements reliability please have a look at Constrained Execution Regions also.

Incognito
A: 

For small, simple objects, you can use a copy-modify-swap idiom. Copy the original object. Make the changes. If all the changes succeeded, swap the copy with the original. (In C++, swap is typically efficient and no-fail.) The destructor will then clean up the original, instead of the copy.

In your case, you'd copy both collections. Remove the object from the first, add it to the second, and then swap the original collections with the copies.

However, this may not be practical if you have large or hard-to-copy objects. In those cases, you generally have to do more work manually.

Adrian McCarthy
+3  A: 

This sort of thing becomes easier when you use immutable collections. In an immutable collection, adding or removing a member does not change the collection, it returns a new collection. (Implementing immutable collections which can do that using acceptably little time and space is a tricky problem.)

But if you have immutable collections, the logic becomes much easier. Suppose you want to move an item from the left collection to the right collection:

newLeft = left.Remove(item);
newRight = right.Add(item);

left and right have not changed; they are immutable. Now the problem you have to solve is an atomic set of left = newLeft and right = newRight, which isn't that hard a problem to solve.

Eric Lippert
See Eric's immutability in C# series for sample immutable collections: http://blogs.msdn.com/ericlippert/archive/tags/Immutability/default.aspx .
Brian