Показать сообщение отдельно
Старый 25.01.2008, 21:12   #1  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,971 / 3267 (116) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Глюки RecordViewCache
Обнаружен баг при использовании кеширования RecordViewCache
В некоторых случаях некорректно происходит выборка данных из закешированной таблицы (запрос на БД вообще не уходит - выборка пустая).
Ax 3.0 SP3 Oracle

Выявлен следующим образом :
В работе семейства классов SalesFormLetter / PurchFormletter сделаны кастомизации приводящие к запросам по InventTrans c использованием фильтра по статусам проводок.

Например такой запрос

X++:
        select sum(qty) from inventTrans
            index hint TransIdIdx
            where inventTrans.inventTransId         == _inventTransId   &&
                (inventTrans.statusIssue == StatusIssue::ReservPhysical ||
                inventTrans.statusIssue == StatusIssue::ReservOrdered   ||
                inventTrans.statusIssue == StatusIssue::OnOrder);
при использовании в методе UpdateNow() SalesFormleter-а может выдать пустую выборку (причем никакого запроса к БД не уходит ! ).

Если выполнять данный запрос в джобе, то все проходит на ура.

Если перед запросом отключить кеширование на таблице
X++:
inventTrans.disableCache(true);
то тоже все проходит на ура как в случае джоба.

К сожалению, построить пример, который бы гарантированно воспроизвел ошибку не получилось.
Есть примеры в рабочей базе для заказа и закупки (для закупки запрос несколько отличается
X++:
        select
            firstOnly
        InventTrans
        order by
            DateFinancial desc
        where
            InventTrans.ItemId        == _itemId &&
            InventTrans.StatusReceipt == StatusReceipt::Purchased &&
            InventTrans.StatusIssue   == StatusIssue::None &&
            (
                InventTrans.TransType     == InventTransType::Purch ||
                InventTrans.TransType     == InventTransType::BOMLine ||
                InventTrans.TransType     == InventTransType::BOMMain ||
                InventTrans.TransType     == InventTransType::InventCounting ||
                InventTrans.TransType     == InventTransType::InventLossProfit ||
                InventTrans.TransType     == InventTransType::InventTransaction
            );
)
для которых глюк воспроизводится гарантированно.

Самое интересное, что если в запросе убрать перечисление статусов, то есть написать так (условие на точное равентсво):

X++:
        select sum(qty) from inventTrans
            index hint TransIdIdx
            where inventTrans.inventTransId         == _inventTransId   &&
                (inventTrans.statusIssue == StatusIssue::ReservPhysical);
или заменить перечисление на диапазон значений, то тоже все отрабатывает.
X++:
        select sum(qty) from inventTrans
            index hint TransIdIdx
            where inventTrans.inventTransId         == _inventTransId   &&
                           inventTrans.StatusIssue >= StatusIssue::ReservPhysical
                     && inventTrans.StatusIssue <= StatusIssue::OnOrder;
Если в методе
\Classes\InventMovement\viewCacheInventTransId
закомментировать создание RecordViewCache
(а именнно в этом методе создается RecordViewCache при работе SalesFormLetter) то тоже глюк исчезает.


Глядя на такое хочется вообще отключить кеширование RecordViewCache в методе
\Classes\InventMovement\viewCacheInventTransId

(тогда оно не будет использоваться при смене статуса проводки).
Вопрос в том не слишком ли сильно просядет в таком случае производительность системы...