You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring-Data-JDBC集成ArcadeDB事务场景count()报错问题咨询

问题背景

使用Spring-Data-JDBC仓库搭配ArcadeDB作为持久化存储时,调用简单的count()方法会抛出运行错误,错误日志如下:

2022-07-10 12:54:33.755 DEBUG 14320 --- [           main] o.s.jdbc.support.JdbcTransactionManager  : Creating new transaction with name [org.springframework.data.jdbc.repository.support.SimpleJdbcRepository.count]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly
2022-07-10 12:54:33.760 DEBUG 14320 --- [           main] o.s.jdbc.support.JdbcTransactionManager  : Acquired Connection [org.postgresql.jdbc.PgConnection@9263c54] for JDBC transaction
2022-07-10 12:54:33.797 DEBUG 14320 --- [           main] o.s.jdbc.datasource.DataSourceUtils      : Setting JDBC Connection [org.postgresql.jdbc.PgConnection@9263c54] read-only
2022-07-10 12:54:33.802 DEBUG 14320 --- [           main] o.s.jdbc.support.JdbcTransactionManager  : Switching JDBC Connection [org.postgresql.jdbc.PgConnection@9263c54] to manual commit
2022-07-10 12:54:34.802 DEBUG 14320 --- [           main] o.s.jdbc.core.JdbcTemplate               : Executing SQL query [SELECT COUNT(*) FROM `Team`]

org.springframework.jdbc.BadSqlGrammarException: StatementCallback; bad SQL grammar [SELECT COUNT(*) FROM `Team`]; nested exception is org.postgresql.util.PSQLException: ERROR: Syntax error on parsing query: Encountered " <READ> "READ "" at line 1, column 7. Was expecting one of:
<EOF> 
<ISOLATION> ...
";" ...
<ISOLATION> ..

相同SQL查询语句通过原生JdbcTemplate执行时可成功运行,执行代码如下:

jdbcTemplate.execute("select count(*) from `Team`")

初步推测报错原因是Repository调用会在事务上下文中执行SQL,而原生JdbcTemplate调用未开启事务。


咨询问题
  1. 是否可实现ArcadeDB与Spring事务管理器正常兼容?
  2. 若无法兼容,是否可以在不启用事务的前提下使用Spring Data Repository?

问题解答

ArcadeDB与Spring事务管理器的兼容性说明

ArcadeDB的PostgreSQL兼容协议目前对JDBC标准事务初始化语句的支持存在缺陷,报错中提到的READ关键字解析失败,本质是Spring的JdbcTransactionManager在开启只读事务时,会先向连接发送SET READ ONLY这类事务设置语句,ArcadeDB的PG协议解析器无法正确识别该语句,未做消费处理,直接将残留的READ关键字拼接到后续执行的COUNT查询前,最终触发SQL语法错误。
可以实现正常兼容,落地方式有两种:

  • 自定义JdbcTransactionManager子类,重写设置连接只读状态的方法,跳过向ArcadeDB连接发送setReadOnly相关指令,避免触发协议层的解析bug
  • 替换使用ArcadeDB官方提供的原生JDBC驱动,不要走PostgreSQL兼容协议连接,官方驱动对JDBC事务规范的支持完整度远高于PG兼容层

无事务使用Spring Data JDBC Repository的实现方式

不需要强制开启事务就能运行Repository方法,可通过以下方式配置:

  • 针对单个查询方法:在自定义Repository接口的对应方法上标注@Transactional(propagation = Propagation.NOT_SUPPORTED),方法执行时会直接挂起当前存在的事务,以非事务态运行,不需要全局调整事务配置
  • 针对全局Repository:自定义JdbcRepositoryFactoryBean,重写其添加事务顾问的逻辑,去掉对所有Repository方法默认添加@Transactional的行为,也可以直接在配置中排除Spring Data JDBC默认的自动事务切面
    注意:非事务态执行写操作会失去原子性保障,只建议对纯查询方法使用非事务配置

内容的提问来源于stack exchange,提问作者Gregor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 02:18:03