我们看看insert语句的执行过程,
如果cs.isTransactionStatement()是true,则表示启动事务执行,
public Result executeCompiledStatement(Statement cs, Object[] pvals) { Result r; if (abortTransaction) { rollback(false); return Result.newErrorResult(Error.error(ErrorCode.X_40001)); } if (sessionContext.depth > 0) { if (sessionContext.noSQL.booleanValue() || cs.isAutoCommitStatement()) { return Result.newErrorResult(Error.error(ErrorCode.X_46000)); } } if (cs.isAutoCommitStatement()) { if (isReadOnly()) { return Result.newErrorResult(Error.error(ErrorCode.X_25006)); } try { /** special autocommit for backward compatibility */ commit(false); } catch (HsqlException e) { database.logger.logInfoEvent("Exception at commit"); } } sessionContext.currentStatement = cs; boolean isTX = cs.isTransactionStatement(); if (!isTX) { if (database.logger.getSqlEventLogLevel() >= SimpleLog.LOG_NORMAL) { sessionContext.setDynamicArguments(pvals); database.logger.logStatementEvent(this, cs, pvals, SimpleLog.LOG_NORMAL); } r = cs.execute(this); sessionContext.currentStatement = null; return r; } while (true) { actionIndex = rowActionList.size(); database.txManager.beginAction(this, cs); cs = sessionContext.currentStatement; if (cs == null) { return Result.newErrorResult(Error.error(ErrorCode.X_07502)); } if (abortTransaction) { rollback(false); sessionContext.currentStatement = null; return Result.newErrorResult(Error.error(ErrorCode.X_40001)); } try { latch.await(); } catch (InterruptedException e) { abortTransaction = true; } if (abortTransaction) { rollback(false); sessionContext.currentStatement = null; return Result.newErrorResult(Error.error(ErrorCode.X_40001)); } database.txManager.beginActionResume(this); // tempActionHistory.add("sql execute " + cs.sql + " " + actionTimestamp + " " + rowActionList.size()); sessionContext.setDynamicArguments(pvals); if (database.logger.getSqlEventLogLevel() >= SimpleLog.LOG_NORMAL) { database.logger.logStatementEvent(this, cs, pvals, SimpleLog.LOG_NORMAL); } r = cs.execute(this); lockStatement = sessionContext.currentStatement; // tempActionHistory.add("sql execute end " + actionTimestamp + " " + rowActionList.size()); endAction(r); if (abortTransaction) { rollback(false); sessionContext.currentStatement = null; return Result.newErrorResult(Error.error(r.getException(), ErrorCode.X_40001, null)); } if (redoAction) { redoAction = false; try { latch.await(); } catch (InterruptedException e) { abortTransaction = true; } } else { break; } } if (sessionContext.depth == 0 && (sessionContext.isAutoCommit.booleanValue() || cs.isAutoCommitStatement())) { try { if (r.mode == ResultConstants.ERROR) { rollback(false); } else { commit(false); } } catch (Exception e) { sessionContext.currentStatement = null; return Result.newErrorResult(Error.error(ErrorCode.X_40001, e)); } } sessionContext.currentStatement = null; return r; }
database.txManager.beginAction(this, cs); 事务执行开始阶段, 这里事务处理用简单的方式进行处理,
事务处理有几种实现,MVCC,2PL两阶段提交,
/** * add session to the end of queue when a transaction starts * (depending on isolation mode) */ public void beginAction(Session session, Statement cs) { if (session.isTransaction) { return; } if (cs == null) { return; } writeLock.lock(); try { if (cs.getCompileTimestamp() < database.schemaManager.getSchemaChangeTimestamp()) { cs = session.statementManager.getStatement(session, cs); session.sessionContext.currentStatement = cs; if (cs == null) { return; } } session.isPreTransaction = true; if (!isLockedMode && !cs.isCatalogLock()) { return; } beginActionTPL(session, cs); } finally { writeLock.unlock(); } }
锁整个表其实就是在当前的TractionManager对象中保存每个表的session对象,也就是每个表操作的每个session对象,这样就是session当前操作需要对这个表加锁,有读锁,写锁。
void lockTablesTPL(Session session, Statement cs) { if (cs == null || session.abortTransaction) { return; } HsqlName[] nameList = cs.getTableNamesForWrite(); for (int i = 0; i < nameList.length; i++) { HsqlName name = nameList[i]; if (name.schema == SqlInvariants.SYSTEM_SCHEMA_HSQLNAME) { continue; } tableWriteLocks.put(name, session); } nameList = cs.getTableNamesForRead(); for (int i = 0; i < nameList.length; i++) { HsqlName name = nameList[i]; if (name.schema == SqlInvariants.SYSTEM_SCHEMA_HSQLNAME) { continue; } tableReadLocks.put(name, session); } }
执行过程 r = cs.execute(this);
中间主要部分是StatementInsert类的这个方法
Result getResult(Session session) { Result resultOut = null; RowSetNavigator generatedNavigator = null; PersistentStore store = baseTable.getRowStore(session); int count; if (generatedIndexes != null) { resultOut = Result.newUpdateCountResult(generatedResultMetaData, 0); generatedNavigator = resultOut.getChainedResult().getNavigator(); } if (isSimpleInsert) { Type[] colTypes = baseTable.getColumnTypes(); Object[] data = getInsertData(session, colTypes, insertExpression.nodes[0].nodes); return insertSingleRow(session, store, data); } RowSetNavigator newDataNavigator = queryExpression == null ? getInsertValuesNavigator(session) : getInsertSelectNavigator(session); count = newDataNavigator.getSize(); if (count > 0) { insertRowSet(session, generatedNavigator, newDataNavigator); } if (baseTable.triggerLists[Trigger.INSERT_AFTER].length > 0) { baseTable.fireTriggers(session, Trigger.INSERT_AFTER, newDataNavigator); } if (resultOut == null) { resultOut = new Result(ResultConstants.UPDATECOUNT, count); } else { resultOut.setUpdateCount(count); } if (count == 0) { session.addWarning(HsqlException.noDataCondition); } return resultOut; }
PersistentStore store = baseTable.getRowStore(session);就是获取这个表对应的内存存储
我们用的是内存数据库,则这里store是org.hsqldb.persist.RowStoreAVLMemory@681070这个对象,待会我们再分析,
终于来到 insertSingleRow插入一条记录操作了
好吧,插入一条记录没那么简单,需要触发触发器操作和外键约束检测
Result insertSingleRow(Session session, PersistentStore store, Object[] data) { if (baseTable.triggerLists[Trigger.INSERT_BEFORE_ROW].length > 0) { baseTable.fireTriggers(session, Trigger.INSERT_BEFORE_ROW, null, data, null); } baseTable.insertSingleRow(session, store, data, null); performIntegrityChecks(session, baseTable, null, data, null); if (session.database.isReferentialIntegrity()) { for (int i = 0, size = baseTable.fkConstraints.length; i < size; i++) { baseTable.fkConstraints[i].checkInsert(session, baseTable, data, true); } } if (baseTable.triggerLists[Trigger.INSERT_AFTER_ROW].length > 0) { baseTable.fireTriggers(session, Trigger.INSERT_AFTER_ROW, null, data, null); } if (baseTable.triggerLists[Trigger.INSERT_AFTER].length > 0) { baseTable.fireTriggers(session, Trigger.INSERT_AFTER, (RowSetNavigator) null); } return Result.updateOneResult; }
/** * Mid level method for inserting single rows. Performs constraint checks and * fires row level triggers. */ Row insertSingleRow(Session session, PersistentStore store, Object[] data, int[] changedCols) { if (identityColumn != -1) { setIdentityColumn(session, data); } if (hasGeneratedValues) { setGeneratedColumns(session, data); } if (hasDomainColumns || hasNotNullColumns) { enforceRowConstraints(session, data); } if (isView) { // may have domain column return null; } Row row = (Row) store.getNewCachedObject(session, data, true); session.addInsertAction(this, store, row, changedCols); return row; }
如果有递增列,则要处理加1操作
/** * If there is an identity column in the table, sets * the value and/or adjusts the identiy value for the table. */ protected void setIdentityColumn(Session session, Object[] data) { if (identityColumn != -1) { Number id = (Number) data[identityColumn]; if (identitySequence.getName() == null) { if (id == null) { id = (Number) identitySequence.getValueObject(); data[identityColumn] = id; } else { identitySequence.userUpdate(id.longValue()); } } else { if (id == null) { id = (Number) session.sessionData.getSequenceValue( identitySequence); data[identityColumn] = id; } } if (session != null) { session.setLastIdentity(id); } } }
setGeneratedColumns 处理有表达式的列数据生成规则,
public void setGeneratedColumns(Session session, Object[] data) { if (hasGeneratedValues) { for (int i = 0; i < colGenerated.length; i++) { if (colGenerated[i]) { Expression e = getColumn(i).getGeneratingExpression(); RangeIteratorBase range = session.sessionContext.getCheckIterator( getDefaultRanges()[0]); range.currentData = data; data[i] = e.getValue(session, colTypes[i]); } } } }
enforceRowConstraints(session, data); 处理列的约束,如果整数是否超过限制等
/** * Enforce max field sizes according to SQL column definition. * SQL92 13.8 */ public void enforceRowConstraints(Session session, Object[] data) { for (int i = 0; i < columnCount; i++) { Type type = colTypes[i]; ColumnSchema column; if (hasDomainColumns && type.isDomainType()) { Constraint[] constraints = type.userTypeModifier.getConstraints(); column = getColumn(i); for (int j = 0; j < constraints.length; j++) { constraints[j].checkCheckConstraint(session, this, column, (Object) data[i]); } } if (colNotNull[i] && data[i] == null) { String constraintName; Constraint c = getNotNullConstraintForColumn(i); if (c == null) { if (ArrayUtil.find(this.primaryKeyCols, i) > -1) { c = this.getPrimaryConstraint(); } } constraintName = c == null ? "" : c.getName().name; column = getColumn(i); String[] info = new String[] { constraintName, tableName.statementName, column.getName().statementName }; throw Error.error(null, ErrorCode.X_23502, ErrorCode.COLUMN_CONSTRAINT, info); } } }
Row row = (Row) store.getNewCachedObject(session, data, true); 申请内存空间
public CachedObject getNewCachedObject(Session session, Object object, boolean tx) { int id; synchronized (this) { id = rowIdSequence++; } Row row = new RowAVL(table, (Object[]) object, id, this); if (tx) { RowAction action = new RowAction(session, table, RowAction.ACTION_INSERT, row, null); row.rowAction = action; } return row; }
RowAction action = new RowAction(session, table,
RowAction.ACTION_INSERT, row,
null);
表操作Represents the chain of insert / delete / rollback / commit actions on a row.
插入之前做的事情太多了,session.addInsertAction(this, store, row, changedCols); 终于来到操作插入的过程了。
public void addInsertAction(Session session, Table table, PersistentStore store, Row row, int[] changedColumns) { RowAction action = row.rowAction; if (action == null) { /* System.out.println("null insert action " + session + " " + session.actionTimestamp); */ throw Error.runtimeError(ErrorCode.GENERAL_ERROR, "null insert action "); } store.indexRow(session, row); session.rowActionList.add(action); row.rowAction = null; }
用AVL tree保存表的数据信息,索引而且每个节点保存数据,普通的AVL数操作,插入过程还加了写锁
/** * Insert a node into the index */ public void insert(Session session, PersistentStore store, Row row) { NodeAVL n; NodeAVL x; boolean isleft = true; int compare = -1; final Object[] rowData = row.getData(); boolean compareRowId = !isUnique || hasNulls(session, rowData); boolean compareSimple = isSimple; writeLock.lock(); try { n = getAccessor(store); x = n; if (n == null) { store.setAccessor(this, ((RowAVL) row).getNode(position)); return; } while (true) { Row currentRow = n.row; compare = 0; if (compareSimple) { compare = colTypes[0].compare(session, rowData[colIndex[0]], currentRow.getData()[colIndex[0]]); if (compare == 0 && compareRowId) { compare = compareRowForInsertOrDelete(session, row, currentRow, compareRowId, 1); } } else { compare = compareRowForInsertOrDelete(session, row, currentRow, compareRowId, 0); } // after the first match and check, all compares are with row id if (compare == 0 && session != null && !compareRowId && session.database.txManager.isMVRows()) { if (!isEqualReadable(session, store, n)) { compareRowId = true; compare = compareRowForInsertOrDelete(session, row, currentRow, compareRowId, colIndex.length); } } if (compare == 0) { if (isConstraint) { Constraint c = ((Table) table).getUniqueConstraintForIndex(this); throw c.getException(row.getData()); } else { throw Error.error(ErrorCode.X_23505, name.statementName); } } isleft = compare < 0; x = n; n = isleft ? x.nLeft : x.nRight; if (n == null) { break; } } x = x.set(store, isleft, ((RowAVL) row).getNode(position)); balance(store, x, isleft); } finally { writeLock.unlock(); } }
/** * Balances part of the tree after an alteration to the index. */ void balance(PersistentStore store, NodeAVL x, boolean isleft) { while (true) { int sign = isleft ? 1 : -1; switch (x.iBalance * sign) { case 1 : x.iBalance = 0; return; case 0 : x.iBalance = -sign; break; case -1 : NodeAVL l = isleft ? x.nLeft : x.nRight; if (l.iBalance == -sign) { x.replace(store, this, l); x.set(store, isleft, l.child(store, !isleft)); l.set(store, !isleft, x); x.iBalance = 0; l.iBalance = 0; } else { NodeAVL r = !isleft ? l.nLeft : l.nRight; x.replace(store, this, r); l.set(store, !isleft, r.child(store, isleft)); r.set(store, isleft, l); x.set(store, isleft, r.child(store, !isleft)); r.set(store, !isleft, x); int rb = r.iBalance; x.iBalance = (rb == -sign) ? sign : 0; l.iBalance = (rb == sign) ? -sign : 0; r.iBalance = 0; } return; } if (x.nParent == null) { return; } isleft = x.nParent == null || x == x.nParent.nLeft; x = x.nParent; } }
我们看下数据,当前有两条记录的数据
执行完之后 endAction(r); 事务处理结束,出错则回滚,成功则提交
public void endAction(Result result) { // tempActionHistory.add("endAction " + actionTimestamp); sessionData.persistentStoreCollection.clearStatementTables(); if (result.mode == ResultConstants.ERROR) { sessionData.persistentStoreCollection.clearResultTables( actionTimestamp); database.txManager.rollbackAction(this); } else { sessionContext .diagnosticsVariables[ExpressionColumn.idx_row_count] = result.mode == ResultConstants.UPDATECOUNT ? Integer.valueOf(result.getUpdateCount()) : ValuePool.INTEGER_0; database.txManager.completeActions(this); } // tempActionHistory.add("endAction ends " + actionTimestamp); }
成功的话当前就是清楚transationManager保存的session需要加锁的表信息了
void endActionTPL(Session session) { if (session.isolationLevel == SessionInterface.TX_REPEATABLE_READ || session.isolationLevel == SessionInterface.TX_SERIALIZABLE) { return; } if (session.sessionContext.currentStatement == null) { // after java function / proc with db access return; } if (session.sessionContext.depth > 0) { // routine or trigger return; } HsqlName[] readLocks = session.sessionContext.currentStatement.getTableNamesForRead(); if (readLocks.length == 0) { return; } writeLock.lock(); try { unlockReadTablesTPL(session, readLocks); final int waitingCount = session.waitingSessions.size(); if (waitingCount == 0) { return; } boolean canUnlock = false; // if write lock was used for read lock for (int i = 0; i < readLocks.length; i++) { if (tableWriteLocks.get(readLocks[i]) != session) { canUnlock = true; break; } } if (!canUnlock) { return; } canUnlock = false; for (int i = 0; i < waitingCount; i++) { Session current = (Session) session.waitingSessions.get(i); if (current.abortTransaction) { canUnlock = true; break; } Statement currentStatement = current.sessionContext.currentStatement; if (currentStatement == null) { canUnlock = true; break; } if (ArrayUtil.containsAny( readLocks, currentStatement.getTableNamesForWrite())) { canUnlock = true; break; } } if (!canUnlock) { return; } resetLocks(session); resetLatchesMidTransaction(session); } finally { writeLock.unlock(); } }
相关推荐
AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!
kolesar_3cd_01_0716
latchman_01_0108
matlab程序代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!
pimpinella_3cd_01_0716
petrilla_01_0308
AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!
内容概要:本文档由张卓老师讲解,重点探讨DeepSeek的技术革新及强化学习对未来AI发展的重要性。文章回顾了AI的历史与发展阶段,详细解析Transformer架构在AI上半场所起到的作用,深入介绍了MoE混合专家以及MLA低秩注意机制等技术特点如何帮助DeepSeek在AI中场建立优势,并探讨了当前强化学习的挑战和边界。文档不仅提及AlphaGo和小游戏等成功案例来说明强化学习的强大力量,还提出了关于未来人工通用智能(AGI)的展望,特别是如何利用强化学习提升现有LLMs的能力和性能。 适用人群:本资料适宜对深度学习感兴趣的研究人员、开发者以及想要深入了解人工智能最新进展的专业人士。 使用场景及目标:通过了解最新的AI技术和前沿概念,在实际工作中能够运用更先进的工具和技术解决问题。同时为那些寻求职业转型或者学术深造的人提供了宝贵的参考。 其他说明:文中提到了许多具体的例子和技术细节,如DeepSeek的技术特色、RL的理论背景等等,有助于加深读者对于现代AI系统的理解和认识。
有师傅小程序开源版v2.4.14 新增报价短信奉告 优化部分细节
AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!
商城二级三级分销系统(小程序+后台含源码).zip
li_3ck_01b_0918
nicholl_3cd_01_0516
媒体关注度是一个衡量公众对某个事件、话题或个体关注程度的重要指标。它主要反映了新闻媒体、社交媒体、博客等对于某一事件、话题或个体的报道和讨论程度。 媒体监督的J-F系数(Janis-Fadner系数)是一种用于测量媒体关注度的指标,特别是用于评估媒体对企业、事件或话题的监督力度。J-F系数基于媒体报道的正面和负面内容来计算,从而为公众、研究者或企业提供一个量化工具,以了解媒体对其关注的方向和强度。 本数据含原始数据、参考文献、代码do文件、最终结果。参考文献中JF系数计算公式。 指标 代码、年份、标题出现该公司的新闻总数、内容出现该公司的新闻总数、正面新闻数全部、中性新闻数全部、负面新闻数全部、正面新闻数原创、中性新闻数原创、负面新闻数原创,媒体监督JF系数。
AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!
AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!
AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!
matlab程序代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!
lusted_3cd_02_0716
pepeljugoski_01_0107