AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 02.07.2008, 12:31   #1  
Oz is offline
Oz
Участник
Аватар для Oz
 
293 / 51 (2) ++++
Регистрация: 22.08.2002
Адрес: Москва
Проблемы с обновлением записи, выбранной для обновления внутри транзакции
Уважаемые господа и товарищи!

Имеем: DAX 4.0 SP2 на MS SQL Server 2000 Dev
А также примерно такой код (упрощённо) в классе ReqTransPoMarkFirm:

X++:
void run();
...
  ttsbegin;
  ...
  this.create();
  ...
  ttscommit;
...
В свою очередь в create:

X++:
select firstonly forupdate reqTrans
  index hint refIdx
  where ...
Далее в недрах класса, после многих преобразований, однако всё в рамках этого же вызова create в какой то момент происходит обновление выбранной здесь записи:

X++:
void updateFirmedReqTrans(...
...
  _reqTrans.InventTransId = _InventTransId;
  _reqTrans.RefType = _refType;
  _reqTrans.RefId  = _refId;
  _reqTrans.IsForecastPurch = NoYes::No;
  _reqTrans.update();
...
И вот тут возникает стандартная ошибка "Операция не может быть завершена, так как запись не выбиралась для обновления. Используйте TTSBEGIN/TTSCOMMIT наряду с выражением FORUPDATE."
Мало того, попытка тупо в этом месте заменить вызов _reqTrans.update() на:

X++:
ttsbegin;
reqTransBuf = ReqTrans::findRecId(_reqTrans.RecId, true);
reqTransBuf.data(_reqTrans);
reqTransBuf.update();
ttscommit;
ситуацию нисколько не изменяет.
Не подскажете ли, что может вызвать такое странное поведение и какой криминал стоит поискать в преобразованиях, производимых в этом классе между выбором записи и её обновлением?

Заранее благодарен всем ответившим.
__________________
Здесь могла быть Ваша реклама!
Старый 02.07.2008, 12:44   #2  
DSPIC is offline
DSPIC
Боец
 
1,077 / 1243 (44) ++++++++
Регистрация: 11.04.2008
возможно проблема в
X++:
reqTransBuf.data(_reqTrans);
В этом случае возможно перезаписывается RecId в курсоре, что убивает его связку с выбранным для записи курсором ?!

edit: Т.е. common.data перезаписывает все поля рекорды, попробуйте не использовать метод .data(), а проинициализировать только нужные поля

Последний раз редактировалось DSPIC; 02.07.2008 в 12:48.
Старый 02.07.2008, 12:50   #3  
Oz is offline
Oz
Участник
Аватар для Oz
 
293 / 51 (2) ++++
Регистрация: 22.08.2002
Адрес: Москва
Цитата:
Сообщение от DSPIC Посмотреть сообщение
возможно проблема в
X++:
reqTransBuf.data(_reqTrans);
В этом случае возможно перезаписывается RecId в курсоре, что убивает его связку с выбранным для записи курсором ?!

edit: Т.е. common.data перезаписывает все поля рекорды, попробуйте не использовать метод .data(), а проинициализировать только нужные поля
Врядли. RecId ведь записывается тот же, что и найденный, так как поиск был именно по recId.
Кроме того, это не объясняет поведение системы без последней правки...
__________________
Здесь могла быть Ваша реклама!
Старый 02.07.2008, 12:56   #4  
glibs is offline
glibs
Member
Сотрудники компании It Box
Most Valuable Professional
Лучший по профессии 2011
Лучший по профессии 2009
 
4,942 / 911 (40) +++++++
Регистрация: 10.06.2002
Адрес: I am from Kyiv, Ukraine. Now I am in Moscow. For private contacts: glibs@hotmail.com
Вы попробуйте. Вам дело говорят.

На всякий случай Global::buf2Buf(common, common).
__________________
С уважением,
glibs®
За это сообщение автора поблагодарили: Oz (1).
Старый 02.07.2008, 13:01   #5  
petr is offline
petr
Участник
Соотечественники
 
561 / 201 (8) ++++++
Регистрация: 30.05.2005
Адрес: Швейцария
Посмотрите в дебагере, действительно ли _reqTrans выбран для обновления? Может по ходу вызовов эта переменная заново была выбрана уже без forUpdate
Старый 02.07.2008, 13:02   #6  
DSPIC is offline
DSPIC
Боец
 
1,077 / 1243 (44) ++++++++
Регистрация: 11.04.2008
Только что проверил - так оно и есть, всё дело в методе .data().
Что касается стандартной системы - ищите, где-то что-то некорректно. Тут никаких подводных камней нет.
Старый 02.07.2008, 13:20   #7  
Oz is offline
Oz
Участник
Аватар для Oz
 
293 / 51 (2) ++++
Регистрация: 22.08.2002
Адрес: Москва
Спасибо
И правда, data(), в отличии от Global::buf2Buf() не подходит. Правда дело не в recId, а в чём то ином.
Вопрос, почему не работает исходный код, к сожалению остаётся открытым... И переходит в разряд теоретических, так как детально с этим разбираться, при условии наличия заплатки, времени пока нет...
Перед обновлением запись помечена, как выбранная для обновления
__________________
Здесь могла быть Ваша реклама!
Старый 02.07.2008, 13:40   #8  
glibs is offline
glibs
Member
Сотрудники компании It Box
Most Valuable Professional
Лучший по профессии 2011
Лучший по профессии 2009
 
4,942 / 911 (40) +++++++
Регистрация: 10.06.2002
Адрес: I am from Kyiv, Ukraine. Now I am in Moscow. For private contacts: glibs@hotmail.com
xRecord.data
Run on: Called
Description
Returns only the data part of the record. Is used to copy data from one record buffer to another rather than making the new buffer into a pointer to the buffer copied from. The buffer copied to has no database position or locks.

Syntax
data( [Common p1] )
Arguments
Returns : Data part of either p1 or of the buffer the method is called on

p1 : the buffer the data should be retrieved from
Example
Table1 t1
Table1 t2

t2 = t1.data();
__________________
С уважением,
glibs®
Старый 02.07.2008, 15:09   #9  
Oz is offline
Oz
Участник
Аватар для Oz
 
293 / 51 (2) ++++
Регистрация: 22.08.2002
Адрес: Москва
Хм... приведённая цитата из докуметации всё же не объясняет такого поведения метода data()...
__________________
Здесь могла быть Ваша реклама!
Старый 02.07.2008, 15:16   #10  
_scorp_ is offline
_scorp_
Участник
Аватар для _scorp_
MCBMSS
 
488 / 369 (13) ++++++
Регистрация: 25.07.2007
Адрес: Москва
Цитата:
The buffer copied to has no database position or locks.
А разве это не объясняет?
Старый 02.07.2008, 15:38   #11  
Oz is offline
Oz
Участник
Аватар для Oz
 
293 / 51 (2) ++++
Регистрация: 22.08.2002
Адрес: Москва
Цитата:
Сообщение от _scorp_ Посмотреть сообщение
А разве это не объясняет?
Так именно это и ожидается!
Копируются только данные в запись, которая была выбрана для обновления в этой транзакции.
Чем в таком случае код

X++:
ttsbegin;
select forupdate someTable where someTable.recId == buffer.recId;
someTable.data(buffer);
someTable.update();
ttscommit;
отличается от

X++:
ttsbegin;
select forupdate someTable where someTable.recId == buffer.recId;
someTable.somefield = buffer.somefield; // Представим что в таблице только одно прикладное поле
someTable.update();
ttscommit;
?
__________________
Здесь могла быть Ваша реклама!
Старый 02.07.2008, 16:05   #12  
glibs is offline
glibs
Member
Сотрудники компании It Box
Most Valuable Professional
Лучший по профессии 2011
Лучший по профессии 2009
 
4,942 / 911 (40) +++++++
Регистрация: 10.06.2002
Адрес: I am from Kyiv, Ukraine. Now I am in Moscow. For private contacts: glibs@hotmail.com
В первом случае someTable переинициализируется.

С чего бы вы думаете buf2buf() написали?

.data() используется для того, чтобы оторвать данные от изначальной табличной переменной. Просто ее значение может измениться в цикле. Или запись кто-то может удалить, если вы ее выбрали без блокировки на обновление. Еще полезно если вы хотите передать курсор из одного объекта в другой, при этом после передачи первый завершает свою работу, а второй еще живет (например, из одной формы передать что-то через parm-метод в другую, при этом первую закрыть).
__________________
С уважением,
glibs®
Старый 02.07.2008, 16:16   #13  
Oz is offline
Oz
Участник
Аватар для Oz
 
293 / 51 (2) ++++
Регистрация: 22.08.2002
Адрес: Москва
Цитата:
Сообщение от glibs Посмотреть сообщение
В первом случае someTable переинициализируется.

С чего бы вы думаете buf2buf() написали?

.data() используется для того, чтобы оторвать данные от изначальной табличной переменной. Просто ее значение может измениться в цикле. Или запись кто-то может удалить, если вы ее выбрали без блокировки на обновление. Еще полезно если вы хотите передать курсор из одного объекта в другой, при этом после передачи первый завершает свою работу, а второй еще живет (например, из одной формы передать что-то через parm-метод в другую, при этом первую закрыть).
Совершенно согласен, что работает именно так. Но в документации всё таки несколько другое написано...
__________________
Здесь могла быть Ваша реклама!
Старый 02.07.2008, 16:24   #14  
glibs is offline
glibs
Member
Сотрудники компании It Box
Most Valuable Professional
Лучший по профессии 2011
Лучший по профессии 2009
 
4,942 / 911 (40) +++++++
Регистрация: 10.06.2002
Адрес: I am from Kyiv, Ukraine. Now I am in Moscow. For private contacts: glibs@hotmail.com
Гм... IMHO там именно это и написано. Я по документации пришел к такому пониманию.
__________________
С уважением,
glibs®
Теги
ax4.0

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Проблемы с Exists Join Logger DAX: Программирование 28 28.04.2010 02:54
Проблемы при использовании шаблона записи Tarrash DAX: Программирование 9 21.08.2007 12:21
Сергей Герасимов: Обновления для Microsoft Dynamics AX 3.0 Blog bot DAX Blogs 0 06.02.2007 15:50
Проблемы работы ERP в многофилиальной и территориально разнесённой компании СНГ. SlavaK DAX: Прочие вопросы 18 02.03.2004 15:25
Автоматическое увеличение значения поля при создании новой записи. sguryev DAX: Программирование 3 06.02.2003 14:00
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 09:00.