作品集展示的网站源码重庆有哪些好玩的地方
- 作者: 五速梦信息网
- 时间: 2026年03月21日 04:57
当前位置: 首页 > news >正文
作品集展示的网站源码,重庆有哪些好玩的地方,小辣椒昆明网站开发,申请网站官网文章基于 RegularTable 来分析和拆解更新操作。 锁模型比较简单#xff0c;方便了解更新的整个流程。并发读写的实现在 MVStore 存储引擎中分析。 主要关注数据更新的实现、事务的提交和回滚。 相关概念 讨论更新操作#xff0c;就需要涉及到事务隔离级别以及事务的概念。 也… 文章基于 RegularTable 来分析和拆解更新操作。 锁模型比较简单方便了解更新的整个流程。并发读写的实现在 MVStore 存储引擎中分析。 主要关注数据更新的实现、事务的提交和回滚。 相关概念 讨论更新操作就需要涉及到事务隔离级别以及事务的概念。 也就是讨论如何控制并发读写的问题、以及undolog 的问题。 ①MVCC multi version concurrency。在 h2database 实现中只有 MVStore 存储引擎支持该特性。MVCC 实现原理参考《Insight h2database MVCC 实现原理》。 /*** Check if multi version concurrency is enabled for this database.* see org.h2.engine.Database#isMultiVersion/
public boolean isMultiVersion() {// this.multiVersion ci.getProperty(MVCC, dbSettings.mvStore);return multiVersion;
}/** 通过设置或者版本确定是否启用 MVStore 存储引擎* see org.h2.engine.DbSettings#mvStore*/
public boolean mvStore get(MV_STORE, Constants.VERSION_MINOR 4);②事务隔离级别 the isolation level. 在 h2database 中通过 LOCK_MODE 体现。不同的锁定模式决定了事务级别。参考命令 SET LOCK_MODE int。 SET LOCK_MODE 命令是数据库级别的影响全局affects all connections。 默认的事务隔离级别为 READ_COMMITTED。但只限在 MVStore 存储引擎中。 对于 RegularTable 只存在两种级别READ_UNCOMMITTED SERIALIZABLE。 READ_UNCOMMITTED即无锁定模式仅用于测试 SERIALIZABLE不同事务session读写互斥。可以防止脏读、不可重复读和幻读但是效率较低因为它会锁定所涉及的全部表直到整个事务完成。
RegularTable 表级独占锁 更新流程中首先会调用 table.lock(session, exclusive true, false); 在 RegularTable 中表会按照 session 粒度控制并发度。这个方法只能当前 session 可重入其他 session 想 lock 成功需要等待当前会话释放锁。 ①独占锁示例
– session 1 更新数据并持有锁
SET AUTOCOMMIT OFF;
update city set code bjx where id 9;– session 2 获取锁超时异常
select * from city where id 5;Timeout trying to lock table CITY; SQL statement:
select * from city where id 5 [50200-184] HYT00/50200②独占锁实现 Java 经典的多线程同步示例。同时包含了死锁检测的实现方案。 /*** 通过会话给表加锁。* 如果要加写锁会存在等待锁的情况。* 如果发生锁超时将抛出DbException异常。如上示例。* param session 当前会话* param exclusive 如果为true表示需要写锁如果为false表示需要读锁。写锁是排他的即在同一时间只能有一个线程持有写锁。读锁是共享的即在同一时间可以有多个线程持有读锁。* see org.h2.table.RegularTable#lock/
public boolean lock(Session session, boolean exclusive, boolean forceLockEvenInMvcc) {int lockMode database.getLockMode();// 无锁模式直接返回。 if (lockMode Constants.LOCK_MODE_OFF) {// 返回是否存在独占 session, 没有使用到约等于无不用关注。return lockExclusiveSession ! null;}// 如果是当前 session 独占相当于锁重入如果一个会话已经持有了这个表的独占锁那么它可以再次获取这个锁而不会被自己阻塞。if (lockExclusiveSession session) {return true;}synchronized (database) {// double check if (lockExclusiveSession session) {return true;}// 读锁共享直接返回。if (!exclusive lockSharedSessions.contains(session)) {return true;}// 写锁进入等待队列session.setWaitForLock(this, Thread.currentThread());waitingSessions.addLast(session);try {// while 循环出队列加锁 or 等待加锁。// 真正的加锁在 doLock2 方法中。根据读写锁不同(exclusive), 执行不同的操作。doLock1(session, lockMode, exclusive);} finally {session.setWaitForLock(null, null);waitingSessions.remove(session);}}return false;
}RegularTable 更新流程 了解独占锁的工作机制后对于数据更新事务的原子性、一致性、隔离级别就没有疑问了。以下主要列出数据更新的主流程比如查找并更新触发器时机。 /** 执行数据更新* see org.h2.command.dml.Update#update/
public int update() {// 记录哪些数据需要更新。RowList rows new RowList(session);try {Table table tableFilter.getTable();session.getUser().checkRight(table, Right.UPDATE);// 尝试添加写锁独占锁table.lock(session, true, false);// 查询需要更新的数据 select by conditionwhile (tableFilter.next()) {if (condition null || Boolean.TRUE.equals(condition.getBooleanValue(session))) {// 旧数据直接查出来的。Row oldRow tableFilter.get();// 新数据根据更新语句重新赋值后的。Row newRow table.getTemplateRow();// 执行 set column 表达式…boolean done false;if (table.fireRow()) {// 数据变更前分发执行触发器。触发器太多可不行❌done table.fireBeforeRow(session, oldRow, newRow);}if (!done) {rows.add(oldRow);rows.add(newRow);}}}// 存储引擎执行真正的数据更新操作。⛳table.updateRows(this, session, rows);if (table.fireRow()) {for (rows.reset(); rows.hasNext();) {// 数据变更后分发执行触发器table.fireAfterRow(session, o, n, false);}}return count;} finally {rows.close();}
}事务控制 因为 RegularTable 存储引擎事务是 SERIALIZABLE 级别。就不存在读写并发的情况。事务的提交不做过多分析主要关注事务回滚的实现。 ①AutoCommit 和其他数据库一样 h2database 会话默认的 AutoCommit true。更新命令执行完成会自动发起 commit 操作。 开启事务的情况下由用户手动发起 commit 操作。 /** 更新命令执行完成后收尾工作之一判断是否需要发起自动提交✔* see org.h2.command.Command#stop/
private void stop() {// AutoCommit 状态自动提交事务。if (session.getAutoCommit()) {session.commit(false);}
}②事务提交 org.h2.command.dml.TransactionCommand#update 命令处理 /** Commit the current transaction. ** see org.h2.engine.Session#commit/
public void commit(boolean ddl) {// 事务持久化机制及时存盘数据库操作记录。if (containsUncommitted()) {database.commit(this);}if (undoLog.size() 0) {undoLog.clear();}// 释放当前会话关联 table 的读写锁。// see org.h2.engine.Session#unlockAllendTransaction();
}③事务回滚 org.h2.command.dml.TransactionCommand#update 命令处理 事务的回滚依赖 undoLog。实现类org.h2.engine.UndoLogRecordundoLog 只存在两种操作 INSERT DELETE。对应到 SQL 操作 Insert SQL: INSERT new, 回滚操作为DELETE new Update SQL: DELETE old, INSERT new, 回滚操作为DELETE new, INSERT old Delete SQL: DELETE old, 回滚操作为INSERT old
/** 事务回滚操作。* 事务回滚的过程就是按照逆序回放事务中的操作undoLog中的操作逆序执行。** param savepoint 如果指定保存点事务将回滚到这个保存点。* param trimToSize if the list should be trimmed*/
public void rollbackTo(Savepoint savepoint, boolean trimToSize) {// 保存点持有的是当前会话开始时 undoLog 的位置。默认都是 0。int index savepoint null ? 0 : savepoint.logIndex;// 当前会话 undoLog 队列逆向回放重置现场。while (undoLog.size() index) {UndoLogRecord entry undoLog.getLast();// 如上的对应操作规则回放操作。entry.undo(this);undoLog.removeLast(trimToSize);}
}
- 上一篇: 作品集用什么网站做嘉兴英文网站建设
- 下一篇: 作图网站做课程表做网站建设分哪些类型
相关文章
-
作品集用什么网站做嘉兴英文网站建设
作品集用什么网站做嘉兴英文网站建设
- 技术栈
- 2026年03月21日
-
作风建设活动网站wordpress图片集插件
作风建设活动网站wordpress图片集插件
- 技术栈
- 2026年03月21日
-
遵义做网站哪个公司最好wordpress为什么不能显示域名
遵义做网站哪个公司最好wordpress为什么不能显示域名
- 技术栈
- 2026年03月21日
-
作图网站做课程表做网站建设分哪些类型
作图网站做课程表做网站建设分哪些类型
- 技术栈
- 2026年03月21日
-
作文网站排行榜前十名好听好记的域名
作文网站排行榜前十名好听好记的域名
- 技术栈
- 2026年03月21日
-
作文网站源码全屋装修公司
作文网站源码全屋装修公司
- 技术栈
- 2026年03月21日






