02.11.2021, 12:09 | #21 |
Участник
|
Проверка показала что исключение с типом Info на самом деле. Warning это в info.add подсовывается.
Цитата:
Беда с транзакцией-то откуда? почему ttscommit не выполняется в
Цитата:
Или у вас по непонятным причинам return false в validateWrite не выполняет как раз корректно, и вместо выхода из метода и перехода в следующий - идет передача управления пользовательскому интерфейсу (со все ещё открытой транзакцией)?
Невнятно ведет себя Акс4, не откатывая транзакцию. В акс2012, повторюсь, откатывает корректно. Кажется и вам такое поведение видится некорректным - не можете в это поверить и ищете причину в наших собственных косяках)) |
|
|
За это сообщение автора поблагодарили: Pandasama (2). |
02.11.2021, 12:47 | #22 |
Участник
|
А вы не могли бы попробовать провести эксперимент.
ttsBegin / ttsCommit методы есть на самом табличном буфере(в частности при работе с времянками in memory лучше использовать их) попробуйте в методе Write задействовать не обычный ttsbegin / commit а одноименные методы на буфере датасорса. Есть подозрение что для работы датасорса формы ядро у вас использовало отдельное соединение к базе и при выбросе исключения откатило именно транзакцию открытую в этом соединении. А основную транзакцию в дефолтном соединении, которую вы открыли написав ttsBegin - не откатило. Вот хотелось бы чтобы там был try catch и в catch проверить открыта ли транзакция на соединении связанном с буфером датасорса (я правда на все 100 не уверен что это отдельное соединение - вот и проверим). Как проверить уровень транзакции - Напрямую на табличном буфере методов нет. Но можно попробовать вызвать tableBuffer.ttsCommit() в цикле со счетчиком. Если уровень транзакции 0 то вызов должен по идее выругаться. |
|
02.11.2021, 15:02 | #23 |
Участник
|
Эмм.. все это странные версии.. ну пусть))
Замена ttsBegin на LedgerJournalTable.ttsbegin() не изменила в поведении ничего абсолютно. Так же вижу в отладчике уровень 1, также журнал создается разносится и при выходе из акс теряется. try catch куда вставлять не понятно. Потому как я уже писал - стоит tts завернуть в try и тогда все корректно откатывается. Вот так работает нормально X++: try { ttsbegin; super(); journalFormTable.datasourceWritePost(); ttscommit; } catch {} Нашей Акс4 сто лет в обед. В функциональности около журнала какбудто ничо не меняется столько же лет. Люди те же, с таким же стажем. Но жалобы характерные начались несколько месяцев назад. Вот и думаю не может быть связано изменение поведения с админской частью? Сервера винды, SQL, терминалы - обновляют регулярно. не могло с этой стороны подвох прийти? Есть еще у когото четверка живая? ) |
|
02.11.2021, 15:44 | #24 |
Участник
|
Данные на формах редактируются в другом UserConnection. Когда вы смотрите в Аксапте активных пользоватей, то для тех, кто работает с формами, видно два разных SPID.
Метод write на датасурсе формы использует один UserConnection. А когда вы пишете в коде ttsbegin - ttscommit, то это применяется ко второму UserConnection. Поэтому когда внутри write выскакивает ошибка, то откатывается транзакция того UserConnection, который дла формы. А для того UserConnection'а, для которго написан в коде ttsbegin - для того транзакция не откатывается. И поэтому ttsLevel не сбрасывается. А try - catch сбрасывает ttsLevel для того ttsbegin, который написан внутри кода для вашего UserConnection. Этим самым и отличаюстя write на источнике данных формы от write на обычной табличной переменной. Ваш ttsbegin-ttscommit не действует на источник данных формы. Если убрать try-catch, то выполнение кода внутри метода write источника данных сразу же прекращается, и не доходит до вызова ttscommit.
__________________
Мои утилиты для Аксапты версий 3.0-2012: http://aceofdatabase.blogspot.com/ Последний раз редактировалось Ace of Database; 02.11.2021 в 15:59. |
|
|
За это сообщение автора поблагодарили: Pandasama (2). |
03.11.2021, 06:30 | #25 |
Участник
|
Цитата:
..Ваш ttsbegin-ttscommit не действует на источник данных формы..
Есть ли у вас пример где эта теория железобетонно подтверждается? У меня есть такой контрпример, что не все так однозначно.. есть два джоба - ttsbegin и ttsabort. есть тестовая форма с таблицей. Ни на таблице ни на форме нет ни одного метода - кода нет вообще. Ну а дальше вы уже догадались.. 1. запускаю форму 2. запускаю джоб ttsbegin 3. в форме заполняю поля записи и закрываю ее. Снова открываю - запись на месте. Закрываю. 4. Запускаю джоб ttsAbort 5. Открываю форму. Записи введенной на шаге 3 больше нет Как это объясняет теория об отдельной жизни форм? Последний раз редактировалось Perc; 03.11.2021 в 06:40. |
|
03.11.2021, 09:52 | #26 |
Участник
|
Цитата:
Сам факт проверки заполнения этих полей происходит автоматически при вызове validateWrite(). Внутри super().Т.е. перехватить эту проверку - невозможно Если надо перехватить проверку на mandatory, то это только "в лоб" до вызова validateWrite() или внутри до вызова super(). Т.е. тупо так X++: if (!common.Field1) { warinig("Укажите значение поля"); } else if (common.vaidateWrite()) { common.write(); }
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... Последний раз редактировалось Владимир Максимов; 03.11.2021 в 10:04. |
|
03.11.2021, 10:20 | #27 |
Участник
|
Цитата:
Речь идет не о коде, который может быть внутри validateWrite, а о полях со свойством mandatory = Yes.
|
|
03.11.2021, 10:22 | #28 |
Участник
|
Цитата:
А вот это и странно. Разве там нет обработки того, что вернет super() ? Должно быть как-то так X++: boolean validateWrite() { boolean ret; ret = super(); // Внутри проверка полей со свойством mandatory = Yes if (ret) { // здесь пользовательские проверки } return ret; }
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
03.11.2021, 11:04 | #29 |
Участник
|
Цитата:
Это не исключение - это инфолог. Просто сообщение.
Последний раз редактировалось Perc; 03.11.2021 в 11:06. |
|
03.11.2021, 13:33 | #30 |
Участник
|
Изначально это ответ был вообще не Вам А во всех последующих сообщениях Вы упорно пишете об исключении типа Warning. Но это не так
Да, тут странно, что прерывание FormDataSource.Write() не обнуляет ttslevel(). Но сильно подозреваю, что проблема в каком-то дополнительном коде. И, скорее всего, где-то в ValidateWrite(). Вот сомневаюсь, что это ошибка на уровне ядра. Тут бы простой тест сделать, раз у Вас уже есть голая форма и голая таблица. Добавьте в таблицу поле с mandatory = Yes, перекройте на форме DataSource.write(), окружив super() транзакцией и проверьте, обнулится ttslevel() или нет?
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
03.11.2021, 14:31 | #31 |
Участник
|
Цитата:
Изначально это ответ был вообще не Вам
Цитата:
А во всех последующих сообщениях Вы упорно пишете об исключении типа Warning. Но это не так
Еще вам за напраслину минус. Я про Warning один раз писал. Проверьте. Потом везде info. А вверху второй страницы я уточнил конкретно: Проверка показала что исключение с типом Info на самом деле. Warning это в info.add подсовывается. Цитата:
Тут бы простой тест сделать..
Но еще раз повторяю для вас. Проблемы нет если сохраняете стандартно - Ctrl+S. В этом случае_DS.validateWrite система сама запускает до _DS.write(). Проблема тогда когда _DS.write() вызывается из кода. Добавляю на форму кнопку с кликедом в котором _DS.wite(). Жмем и проблема проявляется. |
|
04.11.2021, 19:48 | #32 |
Участник
|
Не уверен. Но, вроде бы, в dax4 генерацию новых значений номерных серий делали в отельном соединении. Может, проблема связана с номерными сериями?
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
06.11.2021, 19:24 | #33 |
Участник
|
В чем не уверены? Я свой пример привел.
С вашей стороны есть проверяемый пример подтверждающий обратное? или что имели ввиду Цитата:
Но, вроде бы, в dax4 генерацию новых значений номерных серий делали в отельном соединении. Может, проблема связана с номерными сериями?
|
|
07.11.2021, 19:01 | #34 |
Участник
|
Я так думаю, что Владимир Максимов не уверен в теории, высказанной Ace of Database об отдельном соединении пр работе датасорса формы.
Я тоже в ней не очень уверен - пока не встречался ни с одним кейсом подтверждения такой теории (ну кроме работы с номерными сериями, но это совсем другой кейс). Вот то что Аксапта при сохранении данных датасорса формы вообще не открывает явную транзакцию в MS SQL еще могу предположить (опять же только предположить) - работает неявная транзакция MS SQL. Понятно, что обязательность поля контролируется не на уровне MS SQL, а движком и сам движок выдает исключение, сам же его и перехватывает. В итоге (если предположение правильное), если мы явно открыли транзакцию, то в результате ошибки будет откат и наших изменений, так как в Аксе исключение выбивает на код с первым уровнем транзакции. А если мы транзакцию не открывали, то где-то внутри Аксы своя же ошибка контроля обязательности заполнения поля перехватилась во внутреннем коде работы с формой. Получается, что в базу не записалось, а вот то что делалось вне движка обработки форм, не откатилось. |
|
07.11.2021, 19:29 | #35 |
Участник
|
Еще, насколько помню, порядок вызова тригерных методов курсора в форме (имею ввиду update, validateWrite таблицы, write, validateWrite датасорса формы) какой-то не очень понятный сразу (по крайней мере для меня, может быть логика какая-то есть).
Подробностей не помню, но когда-то достаточно давно даже не помню для каких исследований, перекрывал все эти методы на таблице и датасорсе совсем новой формы и таблицы и отслеживал что вызывается при сохранении. Помню, что был немного удивлен последовательностью и тогда как-то эту последовательность учел при обходе проблемы (а вот что именно тогда было увы, даже намеки не помню ...). |
|
Теги |
стек вызовов, транзакции |
|
|