02.07.2008, 12:31 | #1 |
Участник
|
Проблемы с обновлением записи, выбранной для обновления внутри транзакции
Уважаемые господа и товарищи!
Имеем: DAX 4.0 SP2 на MS SQL Server 2000 Dev А также примерно такой код (упрощённо) в классе ReqTransPoMarkFirm: X++: void run(); ... ttsbegin; ... this.create(); ... ttscommit; ... X++: select firstonly forupdate reqTrans index hint refIdx where ... X++: void updateFirmedReqTrans(...
...
_reqTrans.InventTransId = _InventTransId;
_reqTrans.RefType = _refType;
_reqTrans.RefId = _refId;
_reqTrans.IsForecastPurch = NoYes::No;
_reqTrans.update();
... Мало того, попытка тупо в этом месте заменить вызов _reqTrans.update() на: X++: ttsbegin; reqTransBuf = ReqTrans::findRecId(_reqTrans.RecId, true); reqTransBuf.data(_reqTrans); reqTransBuf.update(); ttscommit; Не подскажете ли, что может вызвать такое странное поведение и какой криминал стоит поискать в преобразованиях, производимых в этом классе между выбором записи и её обновлением? Заранее благодарен всем ответившим.
__________________
Здесь могла быть Ваша реклама! |
|
02.07.2008, 12:44 | #2 |
Боец
|
возможно проблема в
X++: reqTransBuf.data(_reqTrans); edit: Т.е. common.data перезаписывает все поля рекорды, попробуйте не использовать метод .data(), а проинициализировать только нужные поля Последний раз редактировалось DSPIC; 02.07.2008 в 12:48. |
|
02.07.2008, 12:50 | #3 |
Участник
|
Цитата:
Сообщение от DSPIC
возможно проблема в
X++: reqTransBuf.data(_reqTrans); edit: Т.е. common.data перезаписывает все поля рекорды, попробуйте не использовать метод .data(), а проинициализировать только нужные поля Кроме того, это не объясняет поведение системы без последней правки...
__________________
Здесь могла быть Ваша реклама! |
|
02.07.2008, 12:56 | #4 |
Member
|
Вы попробуйте. Вам дело говорят.
На всякий случай Global::buf2Buf(common, common).
__________________
С уважением, glibs® |
|
|
За это сообщение автора поблагодарили: Oz (1). |
02.07.2008, 13:01 | #5 |
Участник
|
Посмотрите в дебагере, действительно ли _reqTrans выбран для обновления? Может по ходу вызовов эта переменная заново была выбрана уже без forUpdate
|
|
02.07.2008, 13:02 | #6 |
Боец
|
Только что проверил - так оно и есть, всё дело в методе .data().
Что касается стандартной системы - ищите, где-то что-то некорректно. Тут никаких подводных камней нет. |
|
02.07.2008, 13:20 | #7 |
Участник
|
Спасибо
И правда, data(), в отличии от Global::buf2Buf() не подходит. Правда дело не в recId, а в чём то ином. Вопрос, почему не работает исходный код, к сожалению остаётся открытым... И переходит в разряд теоретических, так как детально с этим разбираться, при условии наличия заплатки, времени пока нет... Перед обновлением запись помечена, как выбранная для обновления
__________________
Здесь могла быть Ваша реклама! |
|
02.07.2008, 13:40 | #8 |
Member
|
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 |
Участник
|
Хм... приведённая цитата из докуметации всё же не объясняет такого поведения метода data()...
__________________
Здесь могла быть Ваша реклама! |
|
02.07.2008, 15:16 | #10 |
Участник
|
Цитата:
The buffer copied to has no database position or locks.
|
|
02.07.2008, 15:38 | #11 |
Участник
|
Так именно это и ожидается!
Копируются только данные в запись, которая была выбрана для обновления в этой транзакции. Чем в таком случае код 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 |
Member
|
В первом случае someTable переинициализируется.
С чего бы вы думаете buf2buf() написали? .data() используется для того, чтобы оторвать данные от изначальной табличной переменной. Просто ее значение может измениться в цикле. Или запись кто-то может удалить, если вы ее выбрали без блокировки на обновление. Еще полезно если вы хотите передать курсор из одного объекта в другой, при этом после передачи первый завершает свою работу, а второй еще живет (например, из одной формы передать что-то через parm-метод в другую, при этом первую закрыть).
__________________
С уважением, glibs® |
|
02.07.2008, 16:16 | #13 |
Участник
|
Цитата:
Сообщение от glibs
В первом случае someTable переинициализируется.
С чего бы вы думаете buf2buf() написали? .data() используется для того, чтобы оторвать данные от изначальной табличной переменной. Просто ее значение может измениться в цикле. Или запись кто-то может удалить, если вы ее выбрали без блокировки на обновление. Еще полезно если вы хотите передать курсор из одного объекта в другой, при этом после передачи первый завершает свою работу, а второй еще живет (например, из одной формы передать что-то через parm-метод в другую, при этом первую закрыть).
__________________
Здесь могла быть Ваша реклама! |
|
02.07.2008, 16:24 | #14 |
Member
|
Гм... IMHO там именно это и написано. Я по документации пришел к такому пониманию.
__________________
С уважением, glibs® |
|
Теги |
ax4.0 |
|
|