sql - 使用H2 1.4数据库如果读取其他行我可以写入新行

标签 sql concurrency h2

使用 H2 1.4 数据库,如果读取其他行,我可以写入新行吗?

即,如果表中有 1000 行,并且运行一个获取主键 1-10 的 SELECT 查询,INSERT 查询是否可以同时插入一些新行,或者是否必须等待 ( all) 该表上的 SELECT 查询要完成吗?

更新表中的行但没有被任何 SELECT 查询检索到是一种什么情况?

我问这个问题是因为在 H2 1.3 中,我注意到访问数据库的应用程序线程似乎花费了大量时间进行阻塞,现在我已经升级到 1.4 了,情况似乎更好了。但在我的多线程应用程序中,线程总是处理不同的行,因此对我来说,更好地理解锁定在 H2 中的工作原理(使用 MV 存储,之前在 1.3 中使用 PAGE 存储)以及 H2 是否可以锁定非常重要更新时或必须锁定整个表时的各个行。

最佳答案

这取决于您选择的存储引擎。以下所有信息适用于最新版本(1.4.199),旧版本有一些差异。

  • 使用默认的MVStore引擎数据修改操作和SELECT … FOR UPDATE锁定修改(或选择)的行。其他事务无法并行修改锁定的行,但可以读取它们的值。请注意,默认情况下使用已提交读隔离级别,该引擎并不真正支持其他隔离级别。使用读已提交隔离级别,其他事务将看不到并发修改的值,它们将看到旧的值。仅当该事务提交其工作时,新值才可见。使用此引擎,数据库默认以多线程模式运行,因此长时间运行的命令不会阻塞其他 session 。

  • 使用旧版 PageStore 引擎(如果要使用此引擎创建数据库,请将 ;MV_STORE=FALSE 添加到连接 URL),整个表将被锁定以进行写入。这意味着您确实需要在所有事务中以相同的顺序(字母顺序或其他顺序)锁定表,否则可能会出现死锁。由于该引擎数据库默认运行在单线程模式下,您可以显式启用多线程模式,但使用该引擎并不安全。不同的 session 不能同时完成其工作,长时间运行的命令将阻止所有其他 session 。

当您使用新版本的H2打开数据库时,数据库不会从旧的(PageStore)格式转换为新的(MVStore)格式,您必须自己完成。另外旧数据库在新版本上可能会出现严重问题,建议使用SCRIPT TO 'filename.sql'将它们导出到旧版本H2的SQL中。命令并使用 RUNSCRIPT FROM 'filename.sql' 将此脚本加载到具有新版本 H2 的新数据库中命令。即使您选择使用旧引擎,您也需要这样做。如果您有持久数据库,请不要忘记创建定期备份副本(例如,使用 BACKUP TO 'filename.zip' 命令)。

您可以在文档中找到更多详细信息:

https://h2database.com/html/advanced.html#mvcc

https://h2database.com/html/features.html#multiple_connections

关于sql - 使用H2 1.4数据库如果读取其他行我可以写入新行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56594138/

相关文章:

sql - 获取有参数但没有其他参数的用户

MySQL 连接 3 个表的技巧

java - 产生线程时,如何限制可能的最大数量?

c# - 如何使用 linq-to-sql 同时增加页面浏览量?

java - 内存一致性错误与线程干扰

sql-server - 取决于数据库 View 的集成测试

php - 获取相同日期的两个表的记录

sql - 标签和 URL 的数据库设计

java - 玩!没有正确关闭 H2

java - 在H2中, "TRACE_LEVEL_FILE=4"仅适用于本地/嵌入式数据库吗?