Сколько операций рекомендуется выполнять в рамках одной транзакции?

Автор Тема: Сколько операций рекомендуется выполнять в рамках одной транзакции?  (Прочитано 2890 раз)

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

Оффлайн Lemieux

  • ADN OPEN
  • ****
  • Сообщений: 393
  • Карма: 21
Lemieux,
Поясни свою мысль.
Так Вы сами давно подсказали как работать с объектами, созданными во время транзакции.
Код - C# [Выбрать]
  1. document.TransactionManager.QueueForGraphicsFlush();

Оффлайн alz

  • ADN OPEN
  • ***
  • Сообщений: 108
  • Карма: 12
Критичного ничего не вижу, единственное в подобных сценариях я dbCurrent.CloseInput(true); не использую,  к тому же ты говоришь что происходит это уже считай за пределами выложенного куска, так что тут немного не понятно, что же там дальше. Ну как вариант если кад 2025 то возможно дело в попытке чтения открытого файла, раньше помню была у меня прога, проходила по файлам, редактировала, и сохраняла через try catch, естественно на открытых файлах вылетало исключение и прога переходила к следующему.
До 2025 все было норм, что-то изменило, список исключений выдавался - типа не удалось изменить. В 2025 все измененные файлы, если встретился хоть один, выкинувший исключение потребовали исправления при попытке открытия в каде, типа файл поврежден.

Оффлайн Андрей НикифоровАвтор темы

  • ADN OPEN
  • Сообщений: 13
  • Карма: 2
  • Энтузиаст-одиночка
как вариант если кад 2025
Тестирую на AutoCAD 2020
это уже считай за пределами выложенного куска, так что тут немного не понятно, что же там дальше
Если закомментировать все, что дальше идёт, все равно вылетает, т.е. я, видимо, как-то неправильно обращаюсь в этом фрагменте или с файлами, или с памятью. При отладке получаю сообщение, что acdbmgd.dll пытается записать информацию в секцию, защищённую от записи. Т.е. у меня есть подозрение, что я после всего держу какой-то фрагмент занятым, и при попытке его освобождения и происходит падение.

Оффлайн alz

  • ADN OPEN
  • ***
  • Сообщений: 108
  • Карма: 12
Ну, я для себя вывел правило, проверять файл на наличие рядом .dwl файла, если есть даже не пытаться считывать, если требуется изменить, или делать копию куда нить в temp и читать уже спокойно копию.

Оффлайн alz

  • ADN OPEN
  • ***
  • Сообщений: 108
  • Карма: 12
Если закомментировать все, что дальше идёт, все равно вылетает, т.е. я, видимо, как-то неправильно обращаюсь в этом фрагменте или с файлами, или с памятью. При отладке получаю сообщение, что acdbmgd.dll пытается записать информацию в секцию, защищённую от записи. Т.е. у меня есть подозрение, что я после всего держу какой-то фрагмент занятым, и при попытке его освобождения и происходит падение.

ну и как вариант все же попробовать закомментировать строку  dbCurrent.CloseInput(true); всегда работаю без нее и ни разу таких проблем не встречал.

Оффлайн Андрей НикифоровАвтор темы

  • ADN OPEN
  • Сообщений: 13
  • Карма: 2
  • Энтузиаст-одиночка
попробовать закомментировать строку  dbCurrent.CloseInput(true); всегда работаю без нее и ни разу таких проблем не встречал
Есть одна древняя статья, где чел очень убедительно описывает, зачем нужно использовать CloseInput(). Вот ссылка на статью: https://adndevblog.typepad.com/autocad/2012/07/using-readdwgfile-with-net-attachxref-or-objectarx-acdbattachxref.html
Вкратце: приводит две причины - чтобы быть уверенным, что внешний файл прочитался полностью и не произошло кэширование (лично для меня не очень понятно), и второе - CloseInput() "отпускает" внешний файл, и после этого его можно перезаписать. Вот тут как раз все ясно.
Кроме того, видел множество примеров с чтением базы данных из внешнего файла, и в очень многих из них CloseInput() вызывается без объяснений, как само собо разумеющееся.

Оффлайн Андрей НикифоровАвтор темы

  • ADN OPEN
  • Сообщений: 13
  • Карма: 2
  • Энтузиаст-одиночка
Так как ошибка проявлялась стабильно (AutoCAD валился каждый раз), то решил действовать исключением - сначала закомментировал весь код, а затем начал постепенно опять добавлять. Оказалось, что если просто перебирать файлы и читать их базу данных, то ошибка не появляется. Она начинает появляться, как только я начинаю использовать DbDictionaryEnumerator. Я решил немного переделать код - выбросить enumerator и перебирать элементы словаря через DBDictionaryEntry. И с таким способом ошибка пока не появляется. Буду еще тестировать, но есть надежда, что проблема решена. Вот как выглядит конечный результат, который стабильно работает:

Код - C# [Выбрать]
  1.                 // список имен файлов
  2.                 List<string> FileNames = new List<string>();
  3.                 // здесь как-то получаем их имена...
  4.                 // пробегаемся по всем файлам
  5.                 foreach (string sFileName in FileNames)
  6.                 {
  7.                     // создаем пустую базу данных
  8.                     using (Database dbCurrent = new Database(false, true) as Database)
  9.                     {
  10.                         dbCurrent.ReadDwgFile(sFileName, FileOpenMode.OpenForReadAndAllShare, true, string.Empty);
  11.                         dbCurrent.CloseInput(true);
  12.                        
  13.                         //стартуем транзакцию
  14.                         using (Transaction tActiveTransaction = dbCurrent.TransactionManager.StartTransaction())
  15.                         {
  16.                             // получаем коллекцию объектов из словаря LayoutDictionaryId
  17.                             DBDictionary dbdLayouts = (DBDictionary)tActiveTransaction.GetObject(dbCurrent.LayoutDictionaryId, OpenMode.ForRead);
  18.                             // перебор элементов словаря вот таким способом устраняет ошибку
  19.                             foreach (DBDictionaryEntry dicEntry in dbdLayouts)
  20.                             {
  21.                                 Layout layCurrent = (Layout)tActiveTransaction.GetObject(dicEntry.Value, OpenMode.ForRead);
  22.                                 if (layCurrent.ModelType == false)
  23.                                 {
  24.                                     // имя
  25.                                     string LayoutName = layCurrent.LayoutName;
  26.                                     int TabOrder = layCurrent.TabOrder;
  27.                                     Extents2d extPlotArea = layCurrent.PlotWindowArea;
  28.                                 }
  29.                             }
  30.                             tActiveTransaction.Commit();
  31.                         }
  32.                     }
  33.                 }

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

Если кто-то может предположить - почему происходила ошибка при использовании DbDictionaryEnumerator - прошу прокомментировать.

Оффлайн Lemieux

  • ADN OPEN
  • ****
  • Сообщений: 393
  • Карма: 21
Открыть все объекты ForWrite  ;D