Транзакции для объектов C#?

В C или C++ я использовал бы препроцессор вместо если операторы для условного входа.

20
задан queen3 19 November 2009 в 20:05
поделиться

7 ответов

Microsoft работает над этим. Прочтите о программной транзакционной памяти.

Они используют несколько разных синтаксисов:

// For those who like arrows
Atomic.Do(() => { 
    obj.Prop1 = value;
    obj.Prop2 = value;
    obj.Recalculate();
});

// For others who prefer exceptions
try { 
    obj.Prop1 = value;
    obj.Prop2 = value;
    obj.Recalculate();
}
catch (AtomicMarker) {
}

// we may get this in C#:
atomic { 
    obj.Prop1 = value;
    obj.Prop2 = value;
    obj.Recalculate();
}
13
ответ дан 30 November 2019 в 00:23
поделиться

Об этом писал Жувал Лоуи. Вот ссылка на его исходную статью MSDN (я впервые услышал об этой идее в его превосходной книге о WCF). Вот пример кода из MSDN, который выглядит примерно так, как вы хотите:

public class MyClass
{
   Transactional<int> m_Number = new Transactional<int>(3);


public void MyMethod()
   {
      Transactional<string> city = new Transactional<string>("New York");

      using(TransactionScope scope = new TransactionScope())
      {
         city.Value = "London";
         m_Number.Value = 4;
         m_Number.Value++;
         Debug.Assert(m_Number.Value == 5);

         //No call to scope.Complete(), transaction will abort
      }
}
4
ответ дан 30 November 2019 в 00:23
поделиться

Вы можете сделать копию объекта до выполнения методов и установки свойств. Затем, если результат вам не понравится, вы можете просто «откатиться» к копии. При условии, конечно, что у вас нет побочных эффектов, с которыми нужно бороться.

3
ответ дан 30 November 2019 в 00:23
поделиться

Нет, в настоящее время нет ничего подобного, встроенного в .net или C #.

Однако, в зависимости от ваших требований к использованию, вы могли бы реализовать что-то, что сделало бы эту работу за вас.

Ваш класс ObjectTransaction будет сериализовать (или просто дублировать) объект и хранить копию во время транзакции. Если вы вызвали commit , копию можно было бы просто удалить, но если вы вызвали откат, вы могли бы восстановить все свойства исходного объекта из копии.

Это предложение содержит множество предостережений.

  • , если вам нужно использовать отражение для получения свойств (потому что вы хотите, чтобы он обрабатывал любой тип объекта), это будет довольно медленно. То же самое и для сериализации.
  • Если у вас есть дерево объектов, а не простой объект с несколькими свойствами, обработка чего-то подобного в целом для всех типов объектов может быть довольно сложной.
  • Свойства, которые представляют собой списки данных, также являются сложными.
  • Если какие-либо методы получения / установки свойств вызывают изменения (или события), которые имеют эффект, это может вызвать реальные проблемы в другом месте вашего приложения.
  • Это действительно будет работать только для общедоступных свойств.

Все сказанное, проект, над которым я работал несколько лет назад, действительно делал нечто подобное. При очень строгих ограничениях он может работать очень хорошо. Мы поддерживали только объекты данных внутреннего бизнес-уровня. И все они должны были унаследовать от базового интерфейса, который предоставлял некоторые дополнительные метаданные о типах свойств, и были правила о том, какие события могут запускаться установщиками свойств. Мы начинаем транзакцию, а затем привязываем объект к графическому интерфейсу. Если пользователь нажал кнопку ОК, транзакция была просто закрыта,

3
ответ дан 30 November 2019 в 00:23
поделиться

Нет, этот тип поддержки сегодня не существует для обычных управляемых объектов.

2
ответ дан 30 November 2019 в 00:23
поделиться

И здесь снова простое решение - в первую очередь не позволять вашим объектам переходить в недопустимое состояние. Тогда вам не нужно ничего откатывать, вам не нужно вызывать «Validate» и т. Д. Если вы удалите свои сеттеры и начнете думать об отправке сообщений объектам, чтобы что-то сделать с внутренними данными, а не устанавливать свойства, вы раскроет тонкости о вашем домене, которые иначе вы бы не узнали.

2
ответ дан 30 November 2019 в 00:23
поделиться

Как бы то ни было, полноценный STM - это небольшой выход, и я настоятельно рекомендую не использовать собственный.

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

5
ответ дан 30 November 2019 в 00:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: