Показать сообщение отдельно
Старый 14.05.2024, 08:14   #15  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,889 / 3165 (113) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от michel1971 Посмотреть сообщение
Вместо рестарта аоса, можно попробовать дернуть \Classes\ReleaseUpdateBulkCopyDB\flushNextRecIdForTable
О! Не знал про этот метод.

А нам пришлось свое изобретать.
Вот пример метода
(он кроме сброса кешей двигает счетчик RecId, чтобы значения гарантированно не пересеклись. Это пришлось делать, потому что по непонятной пока причине счетчики пересекались после переноса бекапа из рабочей на тестовое окружение. Такое ощущение что пока снимается бекап с рабочей (часа 2 занимает), в бекап в начале процесса попадают одни значения systemSequence, которые к моменту окончания бекапа уже становились неактуальными, так что в некоторых табличках появлялись записи с бОльшими значениями RecId и потом на тестовом окружении ругалась на конфликт уникальности по RecId при создании записи)
X++:
public void processRecIdSequense(TableId _tableId)
{
    systemSequence      systemSequence;

    SystemSequences     systemSequences;
    Common              common;

    void reserve(int numers)
    {
        systemSequence = new systemSequence();
        systemSequence.suspendRecIds(_tableId);
        systemSequence.flushValues(_tableId);
        con2Str([systemSequence.reserveValues(numers, _tableId)]);
        systemSequence.removeRecIdSuspension(_tableId);
    }
    ;

    setPrefix("-");

    if (curext() != "dat")
    {
        throw error("Запуск надо делать в компании dat");
    }

    setPrefix(tableId2name(_tableId));
    common = new DictTable(_tableId).makeRecord();
    common.RecId = SysDictTable::maxRecId_MRC(_tableId);

    select crossCompany systemSequences
        where   systemSequences.Name == "SEQNO"
            &&  systemSequences.Id   == -1
            &&  systemSequences.DataAreaId == 'dat'
            &&  systemSequences.TabId == _tableId;

    if (!systemSequences)
    {
        reserve(1);
        select crossCompany systemSequences
            where   systemSequences.Name == "SEQNO"
                &&  systemSequences.Id   == -1
                &&  systemSequences.DataAreaId == 'dat'
                &&  systemSequences.TabId == _tableId;
    }

    if (!systemSequences)
    {
        this.info(0, "Не найдена запись в systemSequences", true);
        return;
    }

    if (systemSequences.NextVal <= common.RecId)
    {
        this.info(
            1,
            strFmt("Исправляем номерную серию. Был номер %1, стал %2. Разница %3",
                systemSequences.NextVal,
                common.RecId + 1,
                common.RecId + 1 - systemSequences.NextVal
            ),
            true);

        // changeCompany ("dat")
        {
            systemSequences = null;

            ttsBegin;

            new SkipAOSValidationPermission().assert();
            select pessimisticLock systemSequences
                where   systemSequences.Name == "SEQNO"
                    &&  systemSequences.Id   == -1
                    &&  systemSequences.DataAreaId == 'dat'
                    &&  systemSequences.TabId == _tableId;

            systemSequences.skipTTSCheck(true);
            systemSequences.skipDatabaseLog(true);
            systemSequences.selectForUpdate(true);

            if (systemSequences &&
                systemSequences.NextVal <= common.RecId)
            {
                systemSequences.NextVal = common.RecId + 1;
                systemSequences.update();
            }
            ttsCommit;

            CodeAccessPermission::revertAssert();
        }
    }

    reserve(5001);

    this.info(1, "Ok", true);
}
X++:
public static server RecId maxRecId_MRC(TableId _tableId)
{
    SysDictTable                    sysDictTable;
    ResultSet                       resultSet;
    Statement                       statement;

    str                             sqlQuery;

    RecId                           ret;
    ;

    sysDictTable = SysDictTable::newTableId(_tableId);
    sqlQuery = strFmt(@"select max(RecId) from %1", sysDictTable.name(DbBackend::Sql));

    if (sqlQuery)
    {
        new SqlStatementExecutePermission(sqlQuery).assert();

        try
        {
            //BP Deviation documented
            statement = new Connection().createStatement();
            resultSet = statement.executeQuery(sqlQuery);
            if (resultSet.next())
            {
                ret = resultSet.getInt64(1);
            }
        }
        catch
        {
            error("Was errors");
        }
    }

    return ret;
}
А в стандарте так
X++:
public static void flushNextRecIdForTable(TableId _tableId)
{
    systemSequence systemSequence = new systemSequence();

    systemSequence.suspendRecIds(_tableId);
    systemSequence.flushValues(_tableId);
    systemSequence.removeRecIdSuspension(_tableId);
}

Последний раз редактировалось Logger; 14.05.2024 в 08:35.