{"record":{"id":"4f880e0a5e354494","repo":"tursodatabase/turso","slug":"cannot-change-isolation-level-while-transaction-is","errorCode":null,"errorMessage":"Cannot change isolation level while transaction is active.","messagePattern":"Cannot change isolation level while transaction is active\\.","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"bindings/java/src/main/java/tech/turso/core/TursoConnection.java","lineNumber":294,"sourceCode":"    }\n  }\n\n  /**\n   * Sets the transaction isolation level.\n   *\n   * @param level one of the following {@code Connection} constants: {@code\n   *     Connection.TRANSACTION_READ_UNCOMMITTED}, {@code Connection.TRANSACTION_READ_COMMITTED},\n   *     {@code Connection.TRANSACTION_REPEATABLE_READ}, or {@code\n   *     Connection.TRANSACTION_SERIALIZABLE}.\n   * @throws SQLException if a database access error occurs, this method is called on a closed\n   *     connection or the given parameter is not one of the {@code Connection} constants\n   */\n  public void setTransactionIsolation(int level) throws SQLException {\n    synchronized (transactionLock) {\n      checkOpen();\n\n      if (inTransaction) {\n        throw new SQLException(\"Cannot change isolation level while transaction is active.\");\n      }\n\n      if (level != Connection.TRANSACTION_READ_UNCOMMITTED\n          && level != Connection.TRANSACTION_READ_COMMITTED\n          && level != Connection.TRANSACTION_REPEATABLE_READ\n          && level != Connection.TRANSACTION_SERIALIZABLE) {\n        throw new SQLException(\"Invalid transaction isolation level: \" + level);\n      }\n\n      this.transactionIsolation = level;\n    }\n  }\n\n  /**\n   * Retrieves the current transaction isolation level.\n   *\n   * @return the current transaction isolation level\n   * @throws SQLException if a database access error occurs or the connection is closed","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/tursodatabase/turso/blob/244cde92a7df7f9b8b8b7a4075c35a12977e303e/bindings/java/src/main/java/tech/turso/core/TursoConnection.java#L276-L312","documentation":"setTransactionIsolation() refuses to run while a transaction is active on the connection. Transactions begin lazily: once setAutoCommit(false) is set, the first prepared non-BEGIN/COMMIT/ROLLBACK statement starts one, and from that moment changing the isolation level is disallowed until you commit or roll back.","triggerScenarios":"Calling setTransactionIsolation after setAutoCommit(false) plus any statement; connection pools calling setTransactionIsolation on checkout when the previous borrower left a transaction open (no commit/rollback before return); changing isolation mid-unit-of-work.","commonSituations":"Pool adapters (DBCP, HikariCP-style wrappers) that reset isolation on borrow and hit connections returned dirty; application code that begins work, then configures isolation; error paths that skip the cleanup rollback.","solutions":["Set the isolation level before any statement executes: right after getConnection and setAutoCommit(false), before the first prepare","Clean connections before returning them to a pool: rollback any pending work (rollback() is a safe no-op when autoCommit is false and no transaction started)","In pool reset logic, order operations: rollback first, then setAutoCommit, then setTransactionIsolation"],"exampleFix":"// before\nconn.setAutoCommit(false);\nexecuteWork(conn);            // lazy BEGIN fires here\nconn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); // throws\n\n// after\nconn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);\nconn.setAutoCommit(false);\nexecuteWork(conn);\nconn.commit();","handlingStrategy":"validation","validationCode":"// reset to a clean state before changing isolation\nif (!conn.getAutoCommit()) {\n  conn.rollback(); // clears any lazily-started transaction (no-op if none started)\n}\nconn.setTransactionIsolation(level);","typeGuard":null,"tryCatchPattern":"try {\n  conn.setTransactionIsolation(level);\n} catch (SQLException e) {\n  if (e.getMessage().contains(\"transaction is active\")) {\n    if (!conn.getAutoCommit()) conn.rollback();\n    conn.setTransactionIsolation(level); // retry once on a clean connection\n  }\n  throw e;\n}","preventionTips":["Configure isolation immediately after getConnection, before setAutoCommit(false) and any statement","Always return pooled connections clean: rollback pending work before handback","Order pool reset as rollback -> setAutoCommit -> setTransactionIsolation","Remember the lazy-BEGIN rule: with autoCommit off, ANY executed statement opens the transaction that blocks the change"],"tags":["transaction","isolation","java","jdbc","connection-pool"],"backgroundTag":"isolation-change-during-transaction","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"}