Как проводить транзакции на объектах - PullRequest
2 голосов
/ 20 мая 2010

Как я могу имитировать транзакции на объектах. Например, я хочу удалить элемент из одной коллекции, а затем добавить этот же элемент в другую коллекцию в качестве атомарного действия. Можно выполнить много проверок, когда что-то не получилось, и откатить все, но это раздражает. Есть ли способ (без разницы, на каком языке (Java / C ++ / C #)) добиться этого.

Ответы [ 5 ]

3 голосов
/ 21 мая 2010

Подобные вещи становятся проще, когда вы используете неизменяемые коллекции.В неизменяемой коллекции добавление или удаление члена не изменяет коллекцию, а возвращает новую коллекцию.(Реализация неизменяемых коллекций, которые могут сделать это с использованием приемлемо небольшого времени и пространства, является сложной задачей.)

Но если у вас есть неизменные коллекции, логика становится намного проще.Предположим, вы хотите переместить элемент из левой коллекции в правую коллекцию:

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

влево и вправо не изменились;они неизменны.Теперь проблема, которую вам нужно решить, - это атомарный набор left = newLeft и right = newRight, что не так уж сложно решить.

0 голосов
/ 20 мая 2010

Для небольших простых объектов вы можете использовать идиому copy-modify-swap. Скопируйте оригинальный объект. Внесите изменения. Если все изменения были выполнены успешно, замените копию оригиналом. (В C ++ подкачка, как правило, эффективна и без сбоев.) Деструктор затем очистит оригинал, а не копию.

В вашем случае вы скопируете обе коллекции. Удалите объект из первого, добавьте его ко второму, а затем поменяйте местами исходные коллекции с копиями.

Однако это может быть непрактично, если у вас есть большие или трудно копируемые объекты. В этих случаях вам обычно приходится выполнять больше работы вручную.

0 голосов
/ 20 мая 2010

Программная транзакционная память - это один из подходов. Для этого нет технологии, не зависящей от языка.

0 голосов
/ 20 мая 2010

Вы можете использовать метод Херба Саттерса

Как

   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;
}

В основном это означает разделить код на 2 части:

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.
        //——————————
    }

Конечно, я просто имею в виду метод, касающийся ArrayList :). Лучше использовать дженерики, если это возможно, и т.д ...

EDIT

Кроме того, если у вас экстремальные требования к надежности, пожалуйста, посмотрите на Области ограниченного выполнения также.

0 голосов
/ 20 мая 2010
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...