H2介绍 – Java嵌入式数据库

2023-11-05

H2是一个用Java开发的嵌入式数据库,这里指的嵌入式不是手持设备之类的,而是H2数据库作为一个类库,直接嵌入到上层的应用程序中,与应用运行在同一个进程中。

最大的优势在于可以同应用程序打包在一起发布,对于客户端应用来说,非常方便。比如说腾讯QQ或者Mozilla Firefox,用户不可能为了用个软件还得在自己机器上装个MySQL?SQL Server?上述软件就使用嵌入式数据库SQLite来进行客户端本地存储。H2的定位和SQLite一样,属于嵌入式数据库。(H2也可以用在Android上哦)

另一个优势是,写代码时需要写单元测试,与数据库操作相关的功能单元测试都比较不好做,因为有一个环境的问题,而采用H2来进行就要比MySQL要方便的多,首先是启动速度快,而且可以关闭持久化功能,表只存在内存中,每一个用例执行完自动还原到纯净环境。

现在很多开源产品的发布版中所附的测试用例,都是用的H2,目前大家都是把它用作测试。我感觉它的另一个用处是作为内存缓存,NoSQL的一个补充,当某些场景下数据模型必须为关系型,可以拿它当Memcached使,作为后端MySQL/Oracle的一个缓冲层,缓存一些不经常变化但需要频繁访问的数据,比如字典表、权限表。

H2使用非常简单,使用URL: jdbc:h2:~/test 来建立JDBC连接,就会自动创建一个test.h2.db文件和一个test.lock.db文件,前者就是用来存储数据的。只要这个Connection不断开,H2就始终处于运行状态。

H2支持3种运行模式:

1.嵌入式模式。H2运行在应用程序的进程中,执行效率会比较高,但由于不允许其他进程访问,管理起来麻烦点。

 

2.服务器模式。类似于MySQL那种C/S模型,H2运行在一个独立的进程中,应用程序通过TCP协议与其远程通信。优势就是管理方便,而且可以部署在不同的机器上,使用包括集群等特性。

 

3.混合模式。综合以上两种情况,由应用程序首先启动H2,这时对于应用来说H2工作在嵌入式模式,同时H2监听TCP某个端口,等待远程连接,这就是服务器模式,便于管理维护。

 

通常来说,混合模式比较实用。使用jdbc:h2:~/test;AUTO_SERVER=TRUE来建立JDBC连接,就可以开启混合模式。

还可以关闭持久化功能,所有数据都保存在内存中,效率很高。URL:jdbc:h2:mem:test ,同样可以开启混合模式允许远程访问。

对于多版本并发,默认的实现是基于表锁的,读操作加共享锁,写操作加互斥锁,(也就是写会阻塞读)等待锁超时会抛出异常。可以开启MVCC (Multi-Version Concurrent Control) 多版本并发控制模式,URL为jdbc:h2:~/test;MVCC=TRUE,开启MVCC模式后,所有操作都基于行锁,只能看到已提交的数据,写不阻塞读。

举个例子来说明下这个问题:


// 事务1
Connection conn1 = DriverManager.getConnection(jdbcUrl, user, passwd);
conn1.setAutoCommit(false); // 开启事务

ResultSet rs1 = conn1.createStatement().executeQuery(
"select name from students where id = 1 limit 1"); // 事务中读
if (rs1.next())
System.out.println("1. " + rs1.getString("name")); // 修改前

conn1.createStatement().execute(
"update students set name = 'lisi' where id = 1");
// 写操作 注意!完成后故意不提交

ResultSet rs2 = conn1.createStatement().executeQuery(
"select name from students where id = 1 limit 1"); // 事务中读
if (rs2.next())
System.out.println("2. " + rs2.getString("name")); // 修改后

// 事务2
Connection conn2 = DriverManager.getConnection(jdbcUrl, user, passwd);
conn2.setAutoCommit(false); // 开启事务

ResultSet rs3 = conn2.createStatement().executeQuery(
"select name from students where id = 1"); // 事务外读
if (rs3.next())
System.out.println("3. " + rs3.getString("name")); // ?
这个实验的流程是这样的:首先开启一个事务1,读取初始值,修改它,再重新读取这个值。保持事务1没有提交的情况下,在事务2中读取这个值。

如果使用默认模式,则是基于表锁,写阻塞读,事务1的3个操作顺利完成,但事务1没有提交,写锁没有释放。这个时候事务2中会读取这个值,发现数据被锁了,等待一小会后发现仍然无法获取锁,于是第24行抛出异常,控制台打印信息如下:

1. zhangsan
2. lisi
Exception in thread "main" org.h2.jdbc.JdbcSQLException:
Timeout trying to lock table "STUDENTS"; SQL statement:
select name from students where id = 1 [50200-157]
如果开启了MVCC模式,写操作就不会阻塞读操作了,任何时间点只能读到已提交数据。第24行代码正常执行,因为事务1没有提交,所以只能读取到事务1修改前的值,控制台打印信息如下:

1. zhangsan
2. lisi
3. zhangsan
如果应用有并发请求的话,建议开启MVCC模式。

转载于:https://blog.51cto.com/jianshusoft/766947

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

H2介绍 – Java嵌入式数据库 的相关文章

随机推荐

  • Destination Host Unreachable 解决方法

    网上有很多种产生这样情况的原因 DNS设置等 我这里却是由于GATEWAY引起的 没改之前是192 168 0 1 导致一直无法ping 通DNS地址 如 ping 8 8 8 8 一直出现Destination Host Unreacha
  • word删除分节符后之前的格式乱了_分页符&分节符,你知道多少

    Word中 我们经常会遇到分页符和分节符 它们对文档排版 打印 页边距调整 批量调整文档格式等非常重要 分隔符包括 分页符和分节符 分页符 是分页的一种符号 实则就是一条虚线 一般是插在每页的后面 它是位于上一页结束以及下一页开始的位置 分
  • VUE-模板

    Vue js 使用了基于 HTML 的模板语法 允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据 所有 Vue js 的模板都是合法的 HTML 所以能被遵循规范的浏览器和 HTML 解析器解析 在底层的实现上 Vue 将模板编
  • [910]Visual Studio2019安装及使用

    一 下载安装包 下载地址1 https visualstudio microsoft com zh hans rr https www baidu com link url b1goBv9 kKk8djltygQxPnrrNv9bLT0nH
  • Qt学习笔记15:setWindowFlags和 setAttribute

    文章目录 1 setWindowFlags QT WindowFlags 2 setAttribute Qt WA DeleteOnClose true 1 setWindowFlags QT WindowFlags setWindowFl
  • linux入门(五)查找命令总结,含五星级命令find详解

    文章目录 查找命令 which bash 查看bash命令存放的路径 whereis bash 查看bash命令存放的路径 PATH变量 locate 查找文件或目录 默认是模糊查找 find 用于查找文件或目录 默认是精确查找 name
  • JMeter常见错误解决方法—你知道几种

    1 Windows 平台 双击 jmeter bin 目录下 jmeter bat 文件 jmeter 无法启动且报错如下 此问题是没有配置 jdk 环境变量所致 配置好 jdk 环境变量即可 2 若提示 ERRORLEVEL 3 错误 则
  • 1041. 考试座位号(15)

    每个PAT考生在参加考试时都会被分配两个座位号 一个是试机座位 一个是考试座位 正常情况下 考生在入场时先得到试机座位号码 入座进入试机状态后 系统会显示该考生的考试座位号码 考试时考生需要换到考试座位就座 但有些考生迟到了 试机已经结束
  • 分块大法

    所谓分块 就是将原序列处理成各个小块 目的是尽量地达到处理和询问之间的平衡 对于分块类问题 常常可以提取出 在给定区间内进行操作 或询问区间内满足给定条件的元素等 接下来 例题 首先是男神hzwer的博客链接 hzwer 因为下述题目皆由此
  • 基于centos7 mysql主从搭建

    1 在主机上安装好mysql 方便等一会主从搭建在从机上再安装mysql 可以参考以下链接 Centos7安装MySQL详细步骤 在centos7上安装mysql 緑水長流 z的博客 CSDN博客 2 对主机centos7 master 做
  • 数据挖掘分类技术

    1 过分拟合问题 造成原因有 1 噪声造成的过分拟合 因为它拟合了误标记的训练记录 导致了对检验集中记录的误分类 2 根据少量训练记录做出分类决策的模型也容易受过分拟合的影响 由于训练数据缺乏具有代表性的样本 在没有多少训练记录的情况下 学
  • Spine之八——网格和自由变形(FFD)

    Spine 自由变形 FFD 实现乳摇 1 切到装配模式 2 选中图片 3 勾上 Mesh 勾上后就可以编辑网格点了 1 点 Edit Mesh 2 创建网格点 这里是编辑网格点的工具 1 移动 2 增加 3 删除 4 设置网格点 删除所有
  • 【无线点对点网络时延分析和可视化】模拟无线点对点网络中的延迟以及物理层和数据链路层之间的相互作用(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码实现 1 概述 本文模拟无线点对点网络 考虑传输延迟 排队
  • CentOS7安装Docker

    Docker Docker 分为 CE 和 EE 两大版本 CE 即社区版 免费 支持周期 7 个月 EE 即企业版 强调安全 付费使用 支持周期 24 个月 Docker CE 分为 stable test 和 nightly 三个更新频
  • 2020这一年,我完成了这几件大事

    2020这一年 我完成了这几件大事 1 感情 拥有了余生的合伙人 2 工作 找到了自己喜欢的方向 一个长处 3 生活 走走停停 4 读书 兴之所至 1 感情 拥有了余生的合伙人 1 3 关键词 殇 4 6 关键词 静 7 9 关键词 安 1
  • MySQL数据库3--多表查询

    多表查询 多表查询顾名思义就是从多张表中一次性的查询出我们想要的数据 我们通过具体的sql给他们演示 先准备环境 DROP TABLE IF EXISTS emp DROP TABLE IF EXISTS dept 创建部门表 CREATE
  • sqlserver中用户的创建,登录。用户与登录名的区别

    文章目录 前言 一 sql如何创建用户 并将用户添加到相应数据库下 二 用户登录失败 解决方案 三 登录名 用户名 角色三者的区别 前言 sql server中用户的管理 利用sql server创建用户 使用创建的用户进行登录 登录名与用
  • 总结的快速排序

    很多时候对快速排序的具体格式记得都不太清楚 在网上搜了一下 加上自己的理解就摆到了这里 先声明一下 头文件至少要包括以下几个 最好都写上 写上不扣分 include
  • 2023年超实用的27个VSCode插件推荐

    Visual Studio Code 或者称作VS Code 是一个广为人知且评价很高的代码编辑器 它有许多特性和扩展功能 以增强开发体验 使用VS Code的主要好处之一是它的灵活性 允许开发人员根据自己的特定需求进行自定义 此外 VS
  • H2介绍 – Java嵌入式数据库

    H2是一个用Java开发的嵌入式数据库 这里指的嵌入式不是手持设备之类的 而是H2数据库作为一个类库 直接嵌入到上层的应用程序中 与应用运行在同一个进程中 最大的优势在于可以同应用程序打包在一起发布 对于客户端应用来说 非常方便 比如说腾讯