ADN Open CIS
Сообщество программистов Autodesk в СНГ

13/11/2018

Группы транзакций и Assimilation

В продолжение этой дискуссии возникли несколько вопросов об использовании метода TransactionGroup.Assimilate.

Я бы хотел уточнить несколько моментов:

1) Как узнать, сколько транзакций были объединены в группу при вызове метода Assimilate?

2) Если запустить транзакцию перед тем, как будет запущена группа транзакций (в том же контексте API) и вызвать Assimilate, будет ли эта транзакция включена в группу транзакций?

3) Еще одна интересная вещь, которую я обнаружил: в ExternalEvent или методе Execute команды группу команд можно оставить открытой. Вот мой код:

Код - C#: [Выделить]
  1.  
  2. public void Execute(RvtUiApplication app)
  3. {
  4.                 if(WpfTarget.Transactions.ContainsKey(this.GetName()))
  5.                 {
  6.                                Transaction = WpfTarget.Transactions[GetName()];
  7.                                if(Transaction == null)
  8.                                {
  9.                                                Transaction = new Transaction(WpfTarget.CmdVars.DbDoc, GetName());
  10.  
  11.                                                WpfTarget.Transactions[GetName()] = this.Transaction;
  12.                                }
  13.                 }
  14.                 else
  15.                 {
  16.                                WpfTarget.Transactions.Add(GetName(), new Transaction(WpfTarget.CmdVars.DbDoc, GetName()));
  17.                 }
  18.  
  19.                 WpfTarget.TransGroup.Start();
  20.  
  21.                 Transaction.Start();
  22.  
  23.                 Level.Create(WpfTarget.CmdVars.DbDoc, 30);
  24.  
  25.                 Transaction.Commit();
  26.  
  27.                 WpfTarget.TransGroup.Assimilate();
  28. }
  29.  

Не обращайте внимания на начало в коде метода Execute, это для работы моего собственного окна WPF, обратите внимание, что я вызвал только Assimilate, и ни где в коде нет вызовов методов Commit или RollBack.

Я запустил этот код без отладки и всё отработало в Revit без ошибок (тестировал в Revit 2018)

Если запустить код в отладчике VS при выходе из метода отображается примерно такая страница:

 

Означает ли это, что я могу использовать TransactionGroup в "не диалоговом" режиме?

Ответ:

1) Единственный способ узнать, сколько транзакций было объединено в группу транзакций - реализовать собственный счетчик транзакций, увеличивая число при вызове метода Commit(). Группа транзакций объединяет при вызове метода Assimilate только те транзакции, которые были начаты и закоммичены внутри группы.

2) Первый ответ также дает ответ и на второй вопрос - вы не можете запустить группу транзакций в случае, если есть отрытая транзакция. Метод TransactionGroup.Start выдаст ошибку в такой ситуации. Проверить наличие открытых транзакций можно с помощью свойства Document.IsModifiable.

3) Касательно третьего вопроса - технически, Вы, конечно, можете оставить открытой транзакцию или группу транзакций к моменту выхода из метода Execute, но Revit не может сохранить такой контекст, поэтому Revit откатит все изменения (вызовет RollBack), все внесенные изменения будут потеряны. Внутренняя реализация могла измениться за последние три года (прим. переводчика: автор ответа Arnošt Löbel больше не работает в Autodesk), но, скорее всего, по-прежнему, Revit перед запуском команды запускает собственную внутреннюю группу транзакций. После завершения выполнения основного кода команды Revit проверяет, остались ли открытые транзакции или группы транзакций. В этом случае, Revit откатит эти транзакции и саму внутреннюю групп транзакций, запущенную перед началом выполнения. Это сделано из соображений безопасности.

Большое спасибо, Arnošt!

Источник: https://thebuildingcoder.typepad.com/blog/2018/11/more-on-transaction-groups-and-assimilation.html

Обсуждение: http://adn-cis.org/forum/index.php?topic=

Опубликовано 13.11.2018