开发者

How to have transactions on objects

How I can imitate transactions 开发者_Python百科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.


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.


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.


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


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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜