使用 JDBC、spring 框架和 oracle 时出现 ORA04091-table is mutating 错误

Posted

技术标签:

【中文标题】使用 JDBC、spring 框架和 oracle 时出现 ORA04091-table is mutating 错误【英文标题】:getting ORA04091- table is mutating error while working with JDBC ,spring framework and oracle 【发布时间】:2021-06-11 12:31:34 【问题描述】:

我想用 oracle 数据库一次性插入多行。 我正在使用弹簧框架。在使用 executeBatch(); 我收到 ORA-04091 的错误:表 FEED_IMPL 正在变异触发器/函数可能看不到它。

这里是 FeedManager.java 代码:

   //source for DataToInsert comes from a rowMapper class
    //for simplicity I am showing few of the data which is there in List<feedData>
    List<feedData> DataToInsert = [feedData(id =12,source_name =SYD,file_name=syd_210911.json),feedData(id =12,source_name =SYD,file_name=syd_210912.json),feedData(id =12,source_name =SYD,file_name=syd_210913.json)]
 int count =0;
//myJDBCtemplate bean created in dbConfig
    DataSource ds= myJDBCtemplate.getJdbcTemplate().getDataSource();
    Connection conn = ds.getConnection();
    conn.setAutoCommit(false);
    final int batchSize = 200;
    PreparedStatement ps = conn.prepareStatement(query);
    for(feedData insertData: DataToInsert ) 
    ps.setInt(1,insertData.getId());//Id from DataToInsert 
    ps.setString(2,insertData.getSource());//source_name from DataToInsert 
    ps.setString(3,insertData.getFileName());//file_name from DataToInsert 
    ps.addBatch();
if(++count % batchSize == 0) 
ps.executeBatch();
    
 
    int[]affectedRows = ps.executeBatch();
    conn.commit();

使用的查询: INSERT INTO FEED_IMPL(ID,SOURCE_NAME,FILE_NAME)VALUES(?,?,?)

我想一次将 200 多行插入到数据库中,为了问题的简单性,我仅在 DataToInsert 列表中显示了 3 行的数据。

我到这里时出错

表 FEED_IMPL 正在变异,触发器/函数可能看不到它 ORA-06512 :在“FEED_IMPL_NEW_VERSION_TRG”,第 5 行 ORA-04088:期间出错 执行触发器“FEED_IMPL_NEW_VERSION_TRG”

【问题讨论】:

【参考方案1】:

INSERT 声明在这里是受害者。问题出在在feed_impl 表上创建的数据库触发器(名为feed_impl_new_version_trg)中。

通常,这是因为您正在修改表(插入其中,对吗?),而触发器尝试读取同一个表(即包含select ... from feed_impl)。这就是所谓的“变异”。

有几种选择:

也许您根本不需要触发器 可能触发器写得不好,可以修复 如果没有,仍然有解决方法 复合触发器,或 一个包

不能告诉其他任何事情,因为我不知道那个触发器的作用。

【讨论】:

以上是关于使用 JDBC、spring 框架和 oracle 时出现 ORA04091-table is mutating 错误的主要内容,如果未能解决你的问题,请参考以下文章

spring框架 事务 注解配置方式

使用 Spring Boot 和 Spring JDBC 在 oracle 中设置默认模式 = SOMETHING

Spring Roo 和 oracle jdbc 依赖

Spring配置JDBC连接OrcaleMySqlsqlserver

在某些参数类型是用户定义的情况下,如何使用 JDBC/Spring 调用 Oracle 存储过程?

在 Spring 框架中如何更有效地使用 JDBC?