写点什么

【YashanDB 数据库】yasdb jdbc 驱动集成 BeetISQL 中间件,业务 (java) 报 autoAssignKey failure 异常

作者:YashanDB
  • 2024-07-25
    广东
  • 本文字数:936 字

    阅读完需:约 3 分钟

问题现象

BeetISQL 中间件版本:2.13.8.RELEASE


客户在调用 BeetISQL 提供的 api 向 yashandb 的表中执行 batch insert 并将返回 sequence 设置到传入的 java bean 时,报如下异常:


问题的风险及影响

影响业务流程正常执行,无法获得 batch insert 所关联数据库记录设置的 sequence id。


对此业务流程的解释说明:


  • 某表有两列,分别为 tid(数据类型 number), tname(数据类型 varchar2)。其中 tid 不需要业务传入,其值应由另外一个 yashandb 的 sequence 自动生成。

  • 此表对应的 java bean 名称为 TestTable,业务流程在调用 batchInsert(List<TestTable>)时,list 中的元素的 tid 都没有值,实际给 yashandb 下发的 sql 语句为 insert into test_table(tid,tname) values(sequence.nextval, ?)。

  • batchInsert 完成后,业务在遍历 List<TestTable>时,其元素的 tid 已经由中间件经过 jdbc 提供的接口获取并设置回来了。

问题影响的版本

与 yashandb 版本无关

问题发生原因

beetlsql 在此种 batch insert 情况下,prepareStatement 的时候调用的是 conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); 没有指定返回哪一列。


yashan jdbc 驱动会返回生成的 rowid(字符串类型),而 java bean 和数据库中表对应列(tid)是数字型,从字符串向数字型转换的时候,出了异常。

解决方法及规避方式

在 batchInsert 时,不返回自动生成的 sequence id 值 或者 升级到 BeetISQL 3

问题分析和处理过程

根据现网实际表结果,在 yashandb 中创建测试表及 sequence:


create table test_entity(  tid number primary key not null,  age number,  name varchar2(30),  create_date date);create sequence seq_id;
复制代码


然后搭建 java 工程进行问题重现并打断点分析。结合关键日志:


insert into YAOWEI.TEST_ENTITY(TID,AGE,NAME,CREATE_DATE) VALUES (seq_id.nextval,?,?,?) RETURNING ROWID INTO ?
复制代码


中的 returning rowid,判断出是在将 rowid 转换为数字的时候出的问题。


在 BeetISQL 2 中的规避方案就是将 insertBatch 中的 autoDbAssignKey 参数由 true 改为 false。


BeetISQL 3 中的关键源码已经修改,为 conn.prepareStatement(result.jdbcSql, this.getKeyHolderCols(holder, entity.getClass()));


此时可以正常返回 sequence.nextval

经验总结

如下为可直接运行的 beetsql 2 及 3 demo:


beetlsql_demo.rar


beetlsql3_demo.rar

用户头像

YashanDB

关注

全自研国产新型大数据管理系统 2022-02-15 加入

还未添加个人简介

评论

发布
暂无评论
【YashanDB数据库】yasdb jdbc驱动集成BeetISQL中间件,业务(java)报autoAssignKey failure异常_yashandb_YashanDB_InfoQ写作社区