Insight h2database 更新、读写锁以及事务原理

文章基于 RegularTable 来分析和拆解更新操作。

PageStore 存储引擎默认不开启 MVCC,锁模型比较简单,方便了解更新的整个流程。

主要涉及读写锁(事务隔离),数据更新的实现、事务的提交和回滚。

相关概念

讨论更新操作,就需要涉及到事务隔离级别以及事务的概念。

也就是讨论如何控制并发读写的问题、以及undolog 的问题。

①MVCC

multi version concurrency。在 h2database 实现中,默认 MVStore 存储引擎支持该特性。

为了简化事务实现模型,只关注非 MVCC 模式。 MVCC 实现原理参考《Insight h2database MVCC 实现原理》。

/**
 * Check if multi version concurrency is enabled for this database.
 * 使用 PageStore 存储引擎时,使用 MVCC=true 开启。
 * @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, READ_COMMITTED, SERIALIZABLE(默认)。

  • READ_UNCOMMITTED,即无锁定模式(仅用于测试)

  • READ_COMMITTED, 避免了脏读,相比于 SERIALIZABLE,并发性能更好,事务的读写操作不阻塞。开启 MVCC 模式即可。

  • 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
 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值