H2數據庫更新表字段源碼分析

H2數據庫更新表

重複的步驟就不貼了 dml語句都要經過CommandContainer中的update方法咱就直接從這進

@Override
    public int update() {
        recompileIfRequired();
        setProgress(DatabaseEventListener.STATE_STATEMENT_START);
        start();
        session.setLastScopeIdentity(ValueNull.INSTANCE);
        prepared.checkParameters();
        //入口
        int updateCount = prepared.update();
        prepared.trace(startTimeNanos, updateCount);
        setProgress(DatabaseEventListener.STATE_STATEMENT_END);
        return updateCount;
    }

Update類中的update方法

//上面的代碼有點多 主要是將新字段和舊字段放到rows中如下圖
table.updateRows(this, session, rows);
            if (table.fireRow()) {
                rows.invalidateCache();
                for (rows.reset(); rows.hasNext();) {
                    Row o = rows.next();
                    Row n = rows.next();
                    table.fireAfterRow(session, o, n, false);
                }
            }

在這裏插入圖片描述

Table中的updateRows方法

public void updateRows(Prepared prepared, Session session, RowList rows) {
        // in case we need to undo the update
        Session.Savepoint rollback = session.setSavepoint();
        // 移出老字段
        int rowScanCount = 0;
        for (rows.reset(); rows.hasNext();) {
            if ((++rowScanCount & 127) == 0) {
                prepared.checkCanceled();
            }
            Row o = rows.next();
            rows.next();
            try {
                //刪除
                removeRow(session, o);
            } catch (DbException e) {
                if (e.getErrorCode() == ErrorCode.CONCURRENT_UPDATE_1) {
                    session.rollbackTo(rollback, false);
                    session.startStatementWithinTransaction();
                    rollback = session.setSavepoint();
                }
                throw e;
            }
            session.log(this, UndoLogRecord.DELETE, o);
        }
        // 添加新字段
        for (rows.reset(); rows.hasNext();) {
            if ((++rowScanCount & 127) == 0) {
                prepared.checkCanceled();
            }
            rows.next();
            Row n = rows.next();
            try {
                addRow(session, n);
            } catch (DbException e) {
                if (e.getErrorCode() == ErrorCode.CONCURRENT_UPDATE_1) {
                    session.rollbackTo(rollback, false);
                    session.startStatementWithinTransaction();
                    rollback = session.setSavepoint();
                }
                throw e;
            }
            session.log(this, UndoLogRecord.INSERT, n);
        }
    }

MVTable中的移除字段方法 添加和移除差不多 這裏值寫了移除


//MVTable中的方法
@Override
    public void removeRow(Session session, Row row) {
        lastModificationId = database.getNextModificationDataId();
        Transaction t = getTransaction(session);
        long savepoint = t.setSavepoint();
        try {
            for (int i = indexes.size() - 1; i >= 0; i--) {
                Index index = indexes.get(i);
                //調用移除方法
                index.remove(session, row);
            }
        } catch (Throwable e) {
            t.rollbackToSavepoint(savepoint);
            throw DbException.convert(e);
        }
        analyzeIfRequired(session);
    }

MVPrimaryIndex實現了index接口

@Override
    public void remove(Session session, Row row) {
        if (mvTable.getContainsLargeObject()) {
            for (int i = 0, len = row.getColumnCount(); i < len; i++) {
                Value v = row.getValue(i);
                if (v.isLinkedToTable()) {
                    session.removeAtCommit(v);
                }
            }
        }
        //獲得存儲數據的map
        TransactionMap<Value, Value> map = getMap(session);
        try {
            //開始刪除
            Value old = map.remove(ValueLong.get(row.getKey()));
            if (old == null) {
                throw DbException.get(ErrorCode.ROW_NOT_FOUND_WHEN_DELETING_1,
                        getSQL() + ": " + row.getKey());
            }
        } catch (IllegalStateException e) {
            throw mvTable.convertException(e);
        }
    }

往下還有更底層的實現下次再寫附上棧
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章