{"record":{"id":"e742ecfddafbb0ee","repo":"tursodatabase/turso","slug":"cannot-commit-in-autocommit-mode","errorCode":null,"errorMessage":"Cannot commit in autocommit mode.","messagePattern":"Cannot commit in autocommit mode\\.","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"bindings/java/src/main/java/tech/turso/core/TursoConnection.java","lineNumber":220,"sourceCode":"   *\n   * @return true if auto-commit mode is enabled; false otherwise\n   * @throws SQLException if a database access error occurs or the connection is closed\n   */\n  public boolean getAutoCommit() throws SQLException {\n    checkOpen();\n    return autoCommit;\n  }\n\n  /**\n   * Commits the current transaction.\n   *\n   * @throws SQLException if in auto-commit mode, closed, or database error occurs.\n   */\n  public void commit() throws SQLException {\n    synchronized (transactionLock) {\n      checkOpen();\n      if (autoCommit) {\n        throw new SQLException(\"Cannot commit in autocommit mode.\");\n      }\n\n      if (inTransaction) {\n        executeInternal(\"COMMIT\");\n        inTransaction = false;\n      }\n    }\n  }\n\n  /**\n   * Rolls back the current transaction.\n   *\n   * @throws SQLException if in auto-commit mode, closed, or database error occurs.\n   */\n  public void rollback() throws SQLException {\n    synchronized (transactionLock) {\n      checkOpen();\n      if (autoCommit) {","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/tursodatabase/turso/blob/244cde92a7df7f9b8b8b7a4075c35a12977e303e/bindings/java/src/main/java/tech/turso/core/TursoConnection.java#L202-L238","documentation":"commit() requires autoCommit to be false; calling it while the connection is still in the default autocommit mode throws immediately. The driver starts transactions lazily: after setAutoCommit(false), the first prepared non-control statement issues BEGIN, and commit() then runs COMMIT. Committing in autocommit mode is meaningless, hence the guard.","triggerScenarios":"Calling connection.commit() without a prior setAutoCommit(false); toggling setAutoCommit(true) (which commits any pending work) and then calling commit() anyway; code that assumes an implicit transaction is always open.","commonSituations":"Copy-pasted transaction boilerplate missing the setAutoCommit(false) line; connection pools that reset autoCommit to true on return; branching code where one path re-enables autocommit before a shared commit() call.","solutions":["Call conn.setAutoCommit(false) before the work and the commit","Guard the commit: `if (!conn.getAutoCommit()) conn.commit();`","With pools, ensure the borrowed connection's autoCommit state matches what the code expects"],"exampleFix":"// before\nPreparedStatement ps = conn.prepareStatement(\"UPDATE ...\");\nps.executeUpdate();\nconn.commit(); // throws: still autocommit\n\n// after\nconn.setAutoCommit(false);\nPreparedStatement ps = conn.prepareStatement(\"UPDATE ...\");\nps.executeUpdate();\nconn.commit();","handlingStrategy":"validation","validationCode":"// only commit connections actually taken out of autocommit\nif (!conn.getAutoCommit()) {\n  conn.commit();\n}","typeGuard":null,"tryCatchPattern":"try {\n  conn.commit();\n} catch (SQLException e) {\n  if (\"Cannot commit in autocommit mode.\".equals(e.getMessage())) return; // nothing to commit\n  throw e;\n}","preventionTips":["Always pair setAutoCommit(false) with the commit in the same method scope (try/finally shape)","Before committing borrowed pooled connections, check getAutoCommit()","Reset autoCommit deliberately on pool return so the next borrower sees the expected mode"],"tags":["transaction","autocommit","java","jdbc"],"backgroundTag":"commit-in-autocommit-mode","analyzedSha":"244cde92a7df7f9b8b8b7a4075c35a12977e303e","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}