【问题标题】:java.sql.SQLException: Could not commit with auto-commit set on at oracle.jdbc.driver.PhysicalConnection.commit(PhysicalConnection.java:4443)java.sql.SQLException:无法通过在 oracle.jdbc.driver.PhysicalConnection.commit 上设置的自动提交提交(PhysicalConnection.java:4443)
【发布时间】:2014-07-20 03:37:11
【问题描述】:

我只是将新的 jdbc 驱动程序从 classes12.jar 升级到 ojdbc7.jar

我的应用在使用 ojdbc7.jar 运行时抛出异常:

java.sql.SQLException: Could not commit with auto-commit set on
    at oracle.jdbc.driver.PhysicalConnection.commit(PhysicalConnection.java:4443)
    at oracle.jdbc.driver.PhysicalConnection.commit(PhysicalConnection.java:4490)
    at oracle.jdbc.driver.T4CConnection.doSetAutoCommit(T4CConnection.java:943)
    at oracle.jdbc.driver.PhysicalConnection.setAutoCommit(PhysicalConnection.java:4

我的应用程序仍然使用 classes12.jar 正常运行。

我研究过oracle:

以下任何一种情况都会引发此异常:

  • 当自动提交状态设置为 true 并调用提交或回滚方法时
  • 当自动提交的默认状态没有改变并且调用了提交或回滚方法时
  • 当 COMMIT_ON_ACCEPT_CHANGES 属性的值为 true 并且在对行集调用 acceptChanges 方法后调用提交或回滚方法时

但我在源代码中找不到错误。请帮我解释一下这个错误。

【问题讨论】:

  • 尝试设置connection.setAutoCommit(false);
  • 确保您使用的是 JDK7:这就是“ojdbc7”中“7”的含义。 classes12.jar 是 JDK 1.2 的老式 - 你应该在几年前就改变了。不要被“我的应用程序仍然使用 classes12.jar 正常运行”所迷惑。你不应该再使用它。
  • 鉴于调用堆栈,我怀疑驱动程序中存在错误。在自动提交 truefalse 之间切换时(反之亦然),驱动程序必须提交活动事务,并且看起来此提交失败,因为驱动程序处于自动提交状态。另一方面,我希望 Oracle 能够彻底测试他们的驱动程序以实现这些基本状态切换。
  • @MarkRotteveel:请看这个问题。 stackoverflow.com/questions/27272317/…我想我的问题和这个帖子有关

标签: java oracle jdbc


【解决方案1】:

最新的 OJDBC 驱动程序比其他地方更兼容。您可以为遗留代码关闭此行为:

-Doracle.jdbc.autoCommitSpecCompliant=false

这是一个 JVM 选项。

【讨论】:

    【解决方案2】:

    在使用 Oracle JDBC Driver (ojdbc6.jar) 12 或更高版本时会出现此类异常。 12及以上版本的驱动比之前的驱动版本更严格。

    你可以解决问题,你有几个选择:

    1. 将 jar 文件更改为旧版本。(低于 12;通常在迁移到新服务器时出现问题)
    2. 使用以下 JVM 参数设置覆盖新 jar 版本 (ojdbc6.jar) 的行为。

      -Doracle.jdbc.autoCommitSpecCompliant=false

      IBM WAS 用户,请参考this link

    3. 在 Java/SQL 中关闭自动提交:

      Java:

      conn.setAutoCommit(false);

      甲骨文:

      设置自动提交关闭

    【讨论】:

      【解决方案3】:

      根本原因 -

      ojdbc6 中的PhysicalConnector.java

      public void commit(int paramInt) throws SQLException {
          disallowGlobalTxnMode(114);
          if (this.lifecycle != 1) {
              SQLException sQLException = DatabaseError.createSqlException(getConnectionDuringExceptionHandling(), 8);
              sQLException.fillInStackTrace();
              throw sQLException;
          }
          .
          .
      

      ojdbc7 中的PhysicalConnector.java

      public void commit(int paramInt) throws SQLException {
          disallowGlobalTxnMode(114);
          ​if (this.autoCommitSpecCompliant && getAutoCommit()) {
              throw (SQLException)DatabaseError.createSqlException(getConnectionDuringExceptionHandling(), 273).fillInStackTrace();
          }
          if (this.lifecycle != 1) {
              SQLException sQLException = DatabaseError.createSqlException(getConnectionDuringExceptionHandling(), 8);
              sQLException.fillInStackTrace();
              throw sQLException;
          ​}
          .
          .
      

      我们可以看到,在ojdbc7中,已经引入了一段代码。如果autoCommitSpecCompliantgetAutoCommit() 都为真,我们将得到异常。

      两个可用的修复 -

      1. 将 autoCommitSpecCompliant 设置为 false
        下面要设置的JVM参数
        -Doracle.jdbc.autoCommitSpecCompliant=false

      2. connection.commit()之前插入一段代码

      connection.setAutoCommit(false);

      【讨论】:

        【解决方案4】:

        我们是IBM WAS v9,使用ojbc6.jar 上面的配置应用于APP Server、Node agent 和DMGR,然后它就可以工作了。

        -Doracle.jdbc.autoCommitSpecCompliant=false

        经理: 部署管理器 > 流程定义 > Java 虚拟机 修改“通用 JVM 参数”

        节点代理: 节点代理>节点代理>进程定义>Java虚拟机

        WebSphere 应用服务器: 应用程序服务器 > WebSphere_Portal > 进程定义 > Java 虚拟机 修改“通用 JVM 参数”

        【讨论】:

          【解决方案5】:

          在 Hibernate 属性中更改它对我有用

          hibernate.connection.release_mode=auto

          【讨论】:

          • 问题中没有任何内容表明 OP 正在使用 Hibernate。
          猜你喜欢
          • 2020-03-07
          • 2020-05-23
          • 2016-12-26
          • 1970-01-01
          • 1970-01-01
          • 2012-11-30
          • 2015-02-16
          • 2011-06-13
          • 1970-01-01
          相关资源
          最近更新 更多