首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【YashanDB 知识库】statement 级别的触发器在 jdbc 接口调用 executeBatch 时被多次触发

【YashanDB 知识库】statement 级别的触发器在 jdbc 接口调用 executeBatch 时被多次触发

作者头像
用户10349277
发布2025-02-21 11:39:08
发布2025-02-21 11:39:08
28600
代码可运行
举报
运行总次数:0
代码可运行

问题现象

某客户使用 jdbc 接口向 yashandb 的表 A 插入数据。

表 A 上有一个语句级触发器,其内容为在触发时执行 alter sequence 操作;另外还有一个 insert 时的行级触发器,其内容为将每行的部分列赋给新值,这些新值要么来自 sequence.nextval,要么来自于 current_timestamp。

客户向表 A 插入 90 万条数据大概要花费两个半小时。

问题的风险及影响

表中插入数据慢,影响客户系统的处理效率。

问题影响的版本

22.2.14.100 及以前的所有版本

23.2.1.100 及以前的所有版本

问题发生原因

yashandb 的代码 bug,批量执行循环调用 anlExecuteSingle,会多次触发语句级触发器

解决方法及规避方式

版本层面通过修改代码解决。

规避方式不使用语句级触发器

问题分析和处理过程

使用如下的 ddl 来验证语句级触发器被触发了多少次:

代码语言:javascript
代码运行次数:0
运行
复制
drop table trig_test;
create table trig_test(t1 number,t2 number);drop table flag;
create table flag(t number);
create or replace trigger trig_01
before insert or update on trig_test
begin
  insert into flag values(1);
end;
/

使用如下的 java 代码来触发:

代码语言:javascript
代码运行次数:0
运行
复制
//代码占位符
public static void main(String[]args){
    try(Connection conn = DBUtil.getConn()){
        conn.setAutoCommit(false);
        PreparedStatement ps = conn.prepareStatement("insert into trig_test(t1) values(?)");
        for(int i = 0; i < 100; i++){
            ps.setInt(1,i);
            ps.addBatch();
        }
        ps.executeBatch();
        conn.commit();
    }catch (Exception e){
        e.printStackTrace();
    }
}

java 代码执行完成后,查看 flag 表中的总数据量,就可以知道触发器被触发了多少次。yashandb 的实际结果:

可以看到,语句级触发器被触发了 100 次,这是不合理的。

经验总结

了解客户对 jdbc 的使用场景;

灵活使用辅助表来验证触发器的触发次数。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题现象
  • 问题的风险及影响
  • 问题影响的版本
  • 问题发生原因
  • 解决方法及规避方式
  • 问题分析和处理过程
  • 经验总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档