配置HSQLDB Oracle语法兼容后出现表数据只读异常如何解决?
问题原因
该异常是HSQLDB开启Oracle语法兼容模式后触发的默认只读限制导致,与设置sql.syntax_ora的方式无关,核心触发点有两个:
- HSQLDB启用Oracle语法兼容后,默认会将全局事务默认设为只读状态,禁止未显式声明读写权限的DML操作
- 内存库默认事务控制模式为locks,多连接(dbUnit插入数据用一个连接、测试用例用另一个连接)操作同一张表时会触发表锁判定,误报只读错误
解决方案
- 调整JDBC连接URL,补充显式配置覆盖默认只读限制:
将你的db.url调整为如下配置:
两个新增参数说明:db.url=jdbc:hsqldb:mem:unitdb;sql.syntax_ora=true;hsqldb.readonly=false;hsqldb.tx=mvcchsqldb.readonly=false:显式关闭全局库只读限制hsqldb.tx=mvcc:将事务控制模式改为多版本并发控制,支持多连接读写同表不触发锁限制
- 如果你偏好通过SQL语句配置,执行以下语句替代原来的单条语法设置:
注意执行该语句的连接必须是库初始化的超级用户连接(默认sa用户),执行后需要提交事务生效SET DATABASE SQL SYNTAX ORA TRUE; SET DATABASE READONLY FALSE; SET DATABASE TRANSACTION CONTROL MVCC; - 检查dbUnit配置,避免事务隔离问题:
确保dbUnit插入测试数据的连接和测试用例使用的是同一个数据源,且dbUnit操作完成后显式提交事务,不要使用自动回滚的数据源包装类。如果你的测试框架(如Spring Test)默认启用了事务回滚,给测试方法添加@Transactional(readOnly = false)注解覆盖默认只读配置 - 如果上述配置都不生效,升级HSQLDB依赖到2.6.1及以上稳定版本,2.3.x及更早版本的Oracle语法兼容模式存在只读判定的已知bug,升级后即可解决
验证方法
可以先运行最简测试用例验证配置是否生效:
// 用你的配置获取Connection Connection conn = DriverManager.getConnection("jdbc:hsqldb:mem:unitdb;sql.syntax_ora=true;hsqldb.readonly=false;hsqldb.tx=mvcc", "sa", ""); Statement stmt = conn.createStatement(); stmt.executeUpdate("CREATE TABLE test (id NUMBER PRIMARY KEY, name VARCHAR2(20))"); stmt.executeUpdate("INSERT INTO test VALUES (1, 'test')"); // 此处不会再报只读异常 conn.commit();
内容的提问来源于stack exchange,提问作者McAmplifier
相关产品推荐
相关产品推荐

