Открытие объектов без использования транзакции.

Автор Тема: Открытие объектов без использования транзакции.  (Прочитано 31446 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Интересно, Вы это опытным путем установили (255 открывали на чтение? :) ) или где-то есть материалы по этому вопросу?
Autodesk ObjectARX for AutoCAD 20XX: Developer Guide->ObjectARX Introductory Concepts->Database Objects->Opening and Closing Database Objects
Там это всё расписано более подробно, чем я написал.
И можно ли как-то проверить, что объект уже открыт на чтение или запись?
Да:
DBObject.IsReadEnabled
DBObject.IsWriteEnabled
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Здорово! Спасибо!

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
А нет ли случайно каких-то ограничений по использованию методов UpgradeOpen и SwapIdWith при открытии объектов без транзакции?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
А нет ли случайно каких-то ограничений по использованию методов UpgradeOpen и SwapIdWith при открытии объектов без транзакции?
У тебя возникла проблема? Тогда уточни какая. Возможно она комплексная.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Вообще-то UpgradeOpen нельзя вызвать в событии изменения примитива, когда DBObject.IsNotifyEnabled == true
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Да не так просто уточнить, сам пока пытаюсь разобраться...
Была одна транзакция у меня по замене одного блока другим. Все работало, но медленно. Решил заменить на OpenCloseTransaction и посыпалось...
Вроде бы в одном разобрался.
У меня выдавал ошибку метод SwapIdWith. Сперва ругался на то, что объект открыт для чтения. Я поставил перед вызовом метода UpgradeOpen - стало ругаться, что объект открыт для записи.
Получается, что если объект открыт на чтение или запись без использования транзакции, то метод SwapIdWith выдает ошибку (тот объект, id которого используется как аргумент otherId). Сейчас проверяю эту мысль.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Получается, что если объект открыт на чтение или запись без использования транзакции, то метод SwapIdWith выдает ошибку (тот объект, id которого используется как аргумент otherId). Сейчас проверяю эту мысль.
Ну вообще-то этот объект должен быть закрыт. Обычное правило - если передается ObjectId, то объект должен быть закрыт.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Да, теперь все в порядке!
А с обычной транзакцией "прокатывало" подсунуть ObjectId открытого объекта :)
Обычное правило - если передается ObjectId, то объект должен быть закрыт.
Спасибо, учту на будущее!
Самое замечательное, что после исправления этой ошибки, даже с обычной транзакцией замена происходит очень быстро!

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
А с обычной транзакцией "прокатывало" подсунуть ObjectId открытого объекта :)
Обычная транзакция разбаловала программистов. Но иногда это выходит боком так, что найти причину бага становится очень непростой проблемой.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Я имел в виду, нужно ли вызывать этот метод для OpenCloseTransaction?
В этом случае - да.
Не обязательно, т.к.:
Цитата: Андрей Бушман
Обратите внимание, что у Transaction и у OpenCloseTransaction похожее использование, но разное действие по умолчанию:
у Transaction, по умолчанию вызывается метод Abort(), тем самым отменяя все изменения, а у OpenCloseTransaction по умолчанию вызывается метод Close(), тем самым наоборот - сохраняя все выполненные изменения.

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Надо же какое совпадение! Сегодня часа 2 бился над проблемой - почему Civil 3D валится на определенной операции. В итоге, добавление метода Commit в транзакцию (а точнее - обеспечение его 100% вызова в любой ситуации) решило проблему.
Видеодемонстрация (видео длинное получилось, т.к. загружается Civil небыстро):
https://screencast.autodesk.com/main/details/fec694d8-ab7e-4793-a262-d8feb3ae6680

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Надо же какое совпадение! Сегодня часа 2 бился над проблемой - почему Civil 3D валится на определенной операции. В итоге, добавление метода Commit в транзакцию (а точнее - обеспечение его 100% вызова в любой ситуации) решило проблему.Видеодемонстрация (видео длинное получилось, т.к. загружается Civil небыстро):https://screencast.autodesk.com/main/details/fec694d8-ab7e-4793-a262-d8feb3ae6680

Видео мелкое, очень плохо видно. Я не нашёл как можно на весь экран его растянуть. Пишу о том, что сразу же бросилось в глаза:

1. Вложенный блок using (в которой инициализируеся pView) здесь лишний. Он был бы не лишним в том случае, если бы ты открывал объект без использования транзакции и её эмуляции. При эмуляции код следует писать так, как при использовании транзакции, не забывая лишь о том, о чём я писал в предыдущем своём сообщении - пусть Александр Наумович поправит меня, если я неправ...

2. Кроме того, обрати внимание на то, что ты вызываешь Commit во вложенном блоке using, хотя транзакция создаётся во внешнем. Это потенциальное место возникновения проблем, т.е. после вызова Commit транзакция уже не доступна для дальнейшей работы с ней. Например, если по выходу из внутреннего using ты в дальнейшем вдруг решишь обратиться к этой транзакции, добавив пару-тройку соответствующих строк кода, то получишь исключение.

Попробуй удалить вложенный блок using и закомментируй Commit.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Ха. Хотя я был уверен, что Андрей Бушман прав, но оказалось что это не так.
Достаточно проверить такой простенький код:
Код - C# [Выбрать]
  1. // TestOpenClose
  2. [CommandMethod("TestOpenClose")]
  3. public void TestOpenClose()
  4. {
  5.   Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  6.   Database db = doc.Database;
  7.   AcEd.Editor ed = doc.Editor;
  8.   using (OpenCloseTransaction tr =
  9.            doc.TransactionManager.StartOpenCloseTransaction()) {
  10.     Circle cr = new Circle();
  11.     cr.SetDatabaseDefaults(db);
  12.     cr.Radius = 10;
  13.     BlockTableRecord mspace =
  14.              tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
  15.     mspace.AppendEntity(cr);
  16.     tr.AddNewlyCreatedDBObject(cr, true);
  17.     tr.Commit(); // Если это строка закомментарена, то Круг не появляется
  18.   }
  19. }
Т.е. поведение OpenCloseTransaction сделали подобным поведению обычной Transaction.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
1. Вложенный блок using (в которой инициализируеся pView) здесь лишний.
А вот это точно.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Да я понимаю, что лишний. Это так сказать плод творческих поисков :)
Думал: мало ли, вдруг объект остается открытым и потому рушится работа.
Уберу эту конструкцию, хотя, думаю, что на работе кода это никак не скажется.