Можно открыть объект без транзакции... и нарваться на сбои, потому что никто не гарантирует, что объект открыт в МОЕЙ транзакции, а не каком-то другом потоке. Я не мало времени потратил убирая у себя в коде явные и неявные обращения к toptransaction. Да, теперь почти все мелкие статические методы имеют лишний аргумент - транзакцию. А сложные открывают свою. Это захламляет код, но повышает стабильность работы.
Но avc и Вильдар, мои сомнения сняли и передавать транзакцию в метод все таки можно.Можно, можно. На то она и транзакция, чтоб откатить или применить сразу все изменения, не зависимо от того в каком методе они сделаны. Commit само собой должен быть в том методе, где создана транзакция, прямо перед ее уничтожением.
... и нарваться на сбои, потому что никто не гарантирует, что объект открыт в МОЕЙ транзакции, а не каком-то другом потоке.Что-то страшное.
Транзакцию нужно открывать только тогда, когда вы собираетесь менять объект.А для чтения не нужно открывать транзакцию?
Что-то страшноеЭто МОЯ команда в одном потоке, а в это время Автокад по таймерам и событиям живет своей жизнью, открывает новые транзакции. И никто мне не обещает, что эту чужую транзакцию я не словлю в toptransaction. И попробуйте тогда угадать, кто первый уничтожит нужный мне объект, я или чужая транзакция... По факту отказ от обращений к toptransaction привел к исчезновению случайных сбоев во время закрытия транзакций, которые меня сильно доставали. Правда это были не фатальные ошибки, но совершенно непредсказуемые. Вот типичное сообщение о такой ошибке:
Это МОЯ команда в одном потоке, а в это время Автокад по таймерам и событиям живет своей жизнью, открывает новые транзакции.Команда выполняется в главном потоке приложения (единственном), при этом не допускаются обращения к апи автокада из других потоков.
>>How would you handle the case of something wrong after the New DBObject but before the Transaction.AddNewlyCreatedDBObject() then?<<
I prefer do not use transaction at all (as Fenton Webb: http://adndevblog.typepad.com/autocad/2012/06/creating-a-polyline3d-without-using-transactions.html )
Posted by: Alexander Rivilis | 05/18/2014 at 07:14 AM
Можно открыть объект без транзакции:Я думаю без транзакции более правильно так:
Код - C# [Выбрать]
ObjectId.GetObject()
Я думаю без транзакции более правильно так:Имелось ввиду без передачи объекта транзакции явно. Но с запущенной транзакцией.
ObjectId.Open(OpenMode.ForRead)
Если я передам объект транзакции в параметр метода не нарвусь ли я на какие нибудь "подводные камни" при сбое в методе NewMethod()? Или лучше для каждого метода создавать свой экземпляр транзакции?Именно из-за передачи транзакции в метод как параметра проблем не будет. А вот из-за использования транзакции в некоторых случаях могут возникнуть проблемы. Но есть шанс, что вы на них никогда не наткнётесь.
Транзакцию нужно открывать только тогда, когда вы собираетесь менять объект.Не совсем согласен с жёсткостью формулировки. Почему именно нужно? Я, например, очень часто и объекты изменяю без транзакции. И, в то же время, для чтения свойств в какой-нибудь простой команде использую транзакции.
А вообще все зависит от конкретной задачи и архитектуры кодаВот тут абсолютно согласен!
Если я передам объект транзакции в параметр метода не нарвусь ли я на какие нибудь "подводные камни" при сбое в методе NewMethod()? Или лучше для каждого метода создавать свой экземпляр транзакции?По идее блок USING гарантирует вызов метода Dispose в любом случае, даже в случае ошибки в методе NewMethod(). Однако он не спасет от ошибок работы с Database и DbObjects, которые частенько "убивают" AutoCAD, делая дальнейшие вызовы Commit и Dispose у транзакции бессмысленными. (по крайней мере я не доверяю работе AutoCAD после fatal error и не сохраняю результат работы.)