{"record":{"id":"48dc47b082c0c6cf","repo":"mybatis/mybatis-3","slug":"could-not-set-autocommit-to-cause","errorCode":null,"errorMessage":"Could not set AutoCommit to {}. Cause: {}","messagePattern":"Could not set AutoCommit to (.+?)\\. Cause: (.+?)","errorType":"exception","errorClass":"RuntimeSqlException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/jdbc/ScriptRunner.java","lineNumber":183,"sourceCode":"  /**\n   * @deprecated Since 3.5.4, this method is deprecated. Please close the {@link Connection} outside of this class.\n   */\n  @Deprecated\n  public void closeConnection() {\n    try {\n      connection.close();\n    } catch (Exception e) {\n      // ignore\n    }\n  }\n\n  private void setAutoCommit() {\n    try {\n      if (autoCommit != connection.getAutoCommit()) {\n        connection.setAutoCommit(autoCommit);\n      }\n    } catch (Throwable t) {\n      throw new RuntimeSqlException(\"Could not set AutoCommit to \" + autoCommit + \". Cause: \" + t, t);\n    }\n  }\n\n  private void commitConnection() {\n    try {\n      if (!connection.getAutoCommit()) {\n        connection.commit();\n      }\n    } catch (Throwable t) {\n      throw new RuntimeSqlException(\"Could not commit transaction. Cause: \" + t, t);\n    }\n  }\n\n  private void rollbackConnection() {\n    try {\n      if (!connection.getAutoCommit()) {\n        connection.rollback();\n      }","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/jdbc/ScriptRunner.java#L165-L201","documentation":"Before executing a script, ScriptRunner.setAutoCommit aligns the connection's autoCommit flag with the runner's setting; if connection.setAutoCommit(...) throws (driver/DB refuses, connection dead, mid-transaction change disallowed), it is wrapped as RuntimeSqlException with the target value and cause.","triggerScenarios":"new ScriptRunner(connection) then runScript, where the connection cannot switch autoCommit: connection already closed, an active transaction that the driver refuses to alter (e.g. inside a managed transaction), or DB/driver states (e.g. SQL Server XACT_ABORT, connection pools with fixed autoCommit) that reject the change.","commonSituations":"Container-managed or @Transactional connections passed to ScriptRunner; pooled connections recycled mid-run; scripts run against a connection that a prior failure left in a broken state; MariaDB/MySQL drivers during XA.","solutions":["Pass a fresh, free connection not participating in a managed transaction to ScriptRunner.","Match the runner's autoCommit to the connection's actual state: runner.setAutoCommit(connection.getAutoCommit()) so no switch is attempted.","If a managed transaction is required, run script statements through the transactional DataSource honoring its autoCommit instead of toggling it.","Check the cause for connection-closed errors and re-acquire a connection before retrying."],"exampleFix":"// before\nScriptRunner runner = new ScriptRunner(managedTxConnection);\nrunner.setAutoCommit(false); // throws: cannot change autoCommit mid-transaction\n\n// after\nScriptRunner runner = new ScriptRunner(freshConnection);\nrunner.setAutoCommit(false);","handlingStrategy":"validation","validationCode":"// before running, confirm the connection can honor the target autoCommit mode\nif (runner.isAutoCommit() != connection.getAutoCommit()) {\n  try {\n    boolean previous = connection.getAutoCommit();\n    connection.setAutoCommit(runner.isAutoCommit());\n    connection.setAutoCommit(previous); // restore\n  } catch (SQLException e) {\n    throw new IllegalStateException(\"Connection cannot switch autoCommit; pass a free connection to ScriptRunner\", e);\n  }\n}","typeGuard":null,"tryCatchPattern":"catch (RuntimeSqlException e) when e.getMessage() != null && e.getMessage().contains(\"Could not set AutoCommit\") -> treat the connection as unusable for scripting: obtain a new, unmanaged connection and retry once; do not retry on the same connection.","preventionTips":["Give ScriptRunner its own fresh connection, never one inside a container-managed transaction.","Set runner.setAutoCommit(connection.getAutoCommit()) when you cannot control the connection's mode.","Validate connections (isValid) before running scripts in pooled environments."],"tags":["mybatis","scriptrunner","autocommit","transactions","jdbc"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}