Вот тут help.autodesk.com/view/OARX/2021/ENU/?guid=GUID-9DFB5767-F8D6-4A88-87D6-9676C0189369 написано, что такие объекты надо непременно принудительно уничтожить.Получается, что да, надо. И в примерах из той же справки все такие объекты диспозятся до Commit. Вот, например, создание отрезка: https://help.autodesk.com/view/OARX/2021/ENU/?guid=GUID-47E8A12E-2ED4-4E78-ADA3-AAC9B4223C3C . Блок using закрывается перед Commit.
Зачем тогда вообще транзакции, если за ними все равно чистить надо.А вот это - правильный вопрос :)
И в примерах из той же справки все такие объекты диспозятся до Commit.И совершенно не понятно как это может работать... И что будет, если повторно получить этот объект из транзакции? Я во все "мелкие" процедуры передаю транзакцию и есть большой шанс, что где-то кто-то этот объект снова получит из tr.GetObject. там будет null ? или объект пересоздастся заново? откуда, если его еще нет в БД?
Я во все "мелкие" процедуры передаю транзакциюПроблемный сценарий. Я в итоге пришёл к тому, что во все "мелкие" методы передаю только ObjectId. А там внутри либо свою транзакцию запускаю, либо чаще без транзакции просто открываю объект. По выходу из "мелкого" метода объект закрывается.
откуда, если его еще нет в БД?В БД он уже есть, иначе у него не было бы Id. Там же порядок такой - сперва объект добавляется в БД, потом - в транзакцию, а потом только диспозится. В транзакцию невозможно добавить объект, если его нет в БД, если я всё правильно помню.
Получается, что да, надо. И в примерах из той же справки все такие объекты диспозятся до Commit. Вот, например, создание отрезка: https://help.autodesk.com/view/OARX/2021/ENU/?guid=GUID-47E8A12E-2ED4-4E78-ADA3-AAC9B4223C3C . Блок using закрывается перед Commit.Это не код, а полная ерунда. У меня даже слов нет. Дмитрий Загорулькин, мы же уже когда-то обсуждали это и даже смотрели исходники. Если использовать транзакции, то использовать using для объектов, которые можно помещать в базу (наследников DBObject) не следует, ибо если это объект уже добавлен в базу, то завершение using (т.н. метод Dispose) его закроет - фактически вызов метода Close, а если не добавлен, то уничтожит.
Дмитрий Загорулькин, мы же уже когда-то обсуждали это и даже смотрели исходникиЯ что-то такое припоминаю, но к чему тогда пришли - уже не помню :-[
Я тут поспорил с одним специалистом по поводу уничтожения (Dispose) объектов DBObject, которые созданы в моем коде с ноля и приписаны к транзакции (AddNewlyCreatedDBObject).Их нужно самостоятельно диспозить только если у них ObjectId == null, т.е. они не добавлены в базу. Кстати, как сказано в документации, AddNewlyCreatedDBObject можно вызывать только для DBObject, которые уже добавлены в базу, т.е. у них ObjectId != null.
Их нужно самостоятельно диспозить только если у них ObjectId == null, т.е. они не добавлены в базу.
в лучшем случае ничего делать не будет, а в худшем развалит AutoCAD, попытавшись закрыть уже закрытый объект.Цикл такой я попробовал - ничего он не делает, но и никого не разваливает, ни Автокад, ни прочих.
Это не код, а полная ерунда.Однако так тоже работает - я тоже попробовал. И тоже ничего не развалилось. Но "прочим" это сильно помогло от фатала. Похоже кто-то слишком усердно читал документацию на API AutoCAD :)
В БД он уже есть, иначе у него не было бы Id. Там же порядок такой - сперва объект добавляется в БД, потом - в транзакцию, а потом только диспозится.Действительно. Сам же сначала вставляю объект в BTR и получаю Id. И это вполне соответствует логике транзакций в СУБД - все запросы внутри транзакции должны видеть созданную запись. А с наружи - не должны видеть до Commit.
Цикл такой я попробовал - ничего он не делает, но и никого не разваливает, ни Автокад, ни прочих.В одной из старых версий разваливал.
То есть Commit вообще ничего не делает, все уже до него сохранено в БД прямо при изменении каждого свойства.Именно так. И именно поэтому Abort() работает значительно дольше Commit(), так как откатывает все изменения. Такова логика транзакций в AutoCAD. Кстати до AutoCAD 2006, в котором появился AutoCAD .NET API транзакциями мало кто пользовался (я про ObjectARX) - они не были популярны и мало известны. Это уже в AutoCAD .NET API их сделали основным средством работы с базой.
Кстати, как сказано в документации, AddNewlyCreatedDBObject можно вызывать только для DBObject, которые уже добавлены в базуЯ как-то на собственном опыте в этом убедился. Если объекта нет в базе, при попытке добавления его в транзакцию будет исключение с сообщением, что объект не был добавлен в базу.