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

ADN Club => AutoCAD .NET API => Тема начата: simson43 от 19-10-2018, 11:33:15

Название: еще один новичковый вопрос про Transaction
Отправлено: simson43 от 19-10-2018, 11:33:15
Добрый день!

Есть ли разница между
Код - C# [Выбрать]
  1. db.TransactionManager.StartTransaction();
и
Код - C# [Выбрать]
  1. doc.TransactionManager.StartTransaction();
где то встречается один вариант где то другой.
Название: Re: еще один новичковый вопрос про Transaction
Отправлено: Александр Пекшев aka Modis от 19-10-2018, 11:42:09
Вроде как при использовании транзакции у документа после фиксации изменений вызывается регенерация графики, а БД - нет. Где-то тут на форуме есть большая тема по транзакциям. Поищите
Название: Re: еще один новичковый вопрос про Transaction
Отправлено: avc от 19-10-2018, 11:50:50
В API Автокада никакой разницы нет. TopTransaction возвращает последнюю открытую транзакцию, как ее не создавай. А вот в "иных" API перемешивать транзакции документа и БД нельзя. Я, для единообразия, всегда обращаюсь к менеджеру транзакций базы данных.
Название: Re: еще один новичковый вопрос про Transaction
Отправлено: Александр Ривилис от 19-10-2018, 13:11:42
В API Автокада никакой разницы нет.
Есть и достаточно существенная. Если бы ты поисследовал AutoCAD'овские сборки, то увидел бы это. Во-первых, есть два класса TransactionManager:
Autodesk.AutoCAD.DatabaseServices.TransactionManager
Autodesk.AutoCAD.ApplicationServices.TransactionManager
Второй - наследник первого. И второй выполняет дополнительные действия.
Autodesk.AutoCAD.ApplicationServices.TransactionManager.StartTransaction() создаёт не Transaction, а AppTransaction (наследник от Transaction). Существенная разница между AppTransaction и Transaction - в AppTransaction.Commit() кроме Transaction.Commit() выполняется еще и TransactionManager.FlushGraphics();

Код - C# [Выбрать]
  1. internal sealed class AppTransaction : Transaction
  2. {
  3.         private Autodesk.AutoCAD.ApplicationServices.TransactionManager m_mgr = mgr;
  4.  
  5.         public override Autodesk.AutoCAD.DatabaseServices.TransactionManager TransactionManager => m_mgr;
  6.  
  7.         protected internal AppTransaction(IntPtr unmanagedPointer, [MarshalAs(UnmanagedType.U1)] bool autoDelete, Autodesk.AutoCAD.ApplicationServices.TransactionManager mgr)
  8.                 : base(unmanagedPointer, autoDelete)
  9.         {
  10.         }
  11.  
  12.         public sealed override void Commit()
  13.         {
  14.                 Autodesk.AutoCAD.ApplicationServices.TransactionManager obj = (Autodesk.AutoCAD.ApplicationServices.TransactionManager)TransactionManager;
  15.                 base.Commit();
  16.                 obj.FlushGraphics();
  17.         }
  18. }

Название: Re: еще один новичковый вопрос про Transaction
Отправлено: avc от 19-10-2018, 13:20:36
Да, я замечал, что одноименные классы зачем-то сдублированны, но так глубоко не копал. Получается есть еще один повод не использовать менеджер из документа - он на каждом коммите, каждый раз регенить изображение будет. Да?
Название: Re: еще один новичковый вопрос про Transaction
Отправлено: Александр Ривилис от 19-10-2018, 13:39:40
Получается есть еще один повод не использовать менеджер из документа - он на каждом коммите, каждый раз регенить изображение будет. Да?
Я бы сказал с точностью до наоборот. Конечно если у тебя в огромном цикле создаются/комитятся транзакции, то это не дело. И FlushGraphics - это не регенерация, а отображение изменённых в транзакции объектов.
Название: Re: еще один новичковый вопрос про Transaction
Отправлено: avc от 19-10-2018, 14:08:06
Я как раз и имел ввиду, что вместе с коммитом будут существенные задержки на отображение объектов, которые могут быть в экстремальных случаях больше, чем вся работа внутри транзакции. Так что смысла обращаться к такой транзакции не вижу. Лучше уж явно вызвать перерисовку в самом конце обработчика событий или команды. И то надо еще проверить - во многих случаях Автокад сам все переририсовывает без лишних намеков.
Можно использовать транзакции документа для отдельных простых команд с одной транзакцией. Хотя CommandFlags.Redraw - не то же самое сделает?
Внутри сложных методов, где имеет смысл заводить отдельную транзакцию (если вообще имеет смысл), однозначно предпочтительней не обращаться к документу и к его менеджеру транзакций. Потом такой метод можно будет применить, не открывая документа. Да еще и производительность оказывается выигрывает.
Название: Re: еще один новичковый вопрос про Transaction
Отправлено: Александр Ривилис от 19-10-2018, 14:14:12
Хотя CommandFlags.Redraw - не то же самое сделает?
Это совсем из другой оперы. Этот флаг для работы с набором предварительного выбора.
Название: Re: еще один новичковый вопрос про Transaction
Отправлено: simson43 от 19-10-2018, 17:59:55
Помните недавно я в каждом цикле открывал транзакцию менял ширину сегмента полилинии, закрывал транзакцию и по новой.
Поменял на транзакцию бд перерисовка ширины все равно происходит (так и надо). В чем же тогда суть того метода в транзакции документа, который перерисовывает обьекты?
И когда все таки следует использовать каждую транзакцию?
Название: Re: еще один новичковый вопрос про Transaction
Отправлено: Александр Ривилис от 19-10-2018, 18:04:54
И когда все таки следует использовать каждую транзакцию?
Когда хочешь тогда и используй. А можешь вообще не использовать, как я показывал. Разницу между транзакциями я уже объяснял. В твоём случае скорее всего AutoCAD вызывает неявно FlushGraphics в момент, когда ты запрашиваешь очередной сегмент (т.е. при вызове Editor.GetXXX)
Название: Re: еще один новичковый вопрос про Transaction
Отправлено: simson43 от 19-10-2018, 19:38:22
так все неоднозначно..
Спасибо!