{"record":{"id":"708bbfc8867597cc","repo":"tursodatabase/turso","slug":"database-connection-closed","errorCode":null,"errorMessage":"database connection closed","messagePattern":"database connection closed","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"bindings/java/src/main/java/tech/turso/core/TursoConnection.java","lineNumber":64,"sourceCode":"   * Creates a connection using an existing TursoDB instance. This is useful for encrypted databases\n   * created with TursoDB.createWithEncryption().\n   *\n   * @param url e.g. \"jdbc:turso:fileName\"\n   * @param database an existing TursoDB instance\n   */\n  public TursoConnection(String url, TursoDB database) throws SQLException {\n    this.url = url;\n    this.database = database;\n    this.connectionPtr = this.database.connect();\n  }\n\n  private static TursoDB open(String url, String filePath, Properties properties)\n      throws SQLException {\n    return TursoDB.create(url, filePath);\n  }\n\n  public void checkOpen() throws SQLException {\n    if (isClosed()) throw new SQLException(\"database connection closed\");\n  }\n\n  public String getUrl() {\n    return url;\n  }\n\n  public void close() throws SQLException {\n    if (isClosed()) {\n      return;\n    }\n\n    // Roll back any pending transaction before closing\n    synchronized (transactionLock) {\n      if (inTransaction) {\n        try {\n          executeInternal(\"ROLLBACK\");\n        } catch (SQLException e) {\n          // Log but don't throw - we're closing anyway","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/tursodatabase/turso/blob/bad083fafbefdeae9a42ec19bdaaad8918dcf411/bindings/java/src/main/java/tech/turso/core/TursoConnection.java#L46-L82","documentation":"SQLException thrown by TursoConnection.checkOpen() when a JDBC method is invoked on a connection whose close() has already completed (the closed flag is set). Every state-touching method — prepare, commit, rollback, setAutoCommit, getAutoCommit, setTransactionIsolation, getTransactionIsolation — calls checkOpen() first, matching standard JDBC 'connection closed' behavior.","triggerScenarios":"conn.prepareStatement(...) after conn.close(); using a connection outside its try-with-resources block; a connection pool handing out a connection that another thread or an eviction policy already closed.","commonSituations":"Cleanup code closing early while a background job still uses the connection; pool eviction racing active borrowers; test fixtures closing a shared connection in @AfterAll while later suites reuse it; wrappers that close on error paths but continue processing.","solutions":["Check conn.isClosed() before use and reopen or re-borrow from the pool when true","Scope connections with try-with-resources so close() happens after the last use","Fix pool configuration (test-on-borrow, sane eviction) so connections are not closed underneath active users"],"exampleFix":"// before\ntry (Connection conn = DriverManager.getConnection(url)) {\n  doWork(conn);\n}\nconn.prepareStatement(sql); // SQLException: database connection closed\n\n// after\ntry (Connection conn = DriverManager.getConnection(url)) {\n  doWork(conn);\n  conn.prepareStatement(sql); // still inside the resource scope\n}","handlingStrategy":"validation","validationCode":"if (conn.isClosed()) {\n  conn = DriverManager.getConnection(url, props); // or re-borrow from the pool\n}\ntry (var ps = conn.prepareStatement(sql)) {\n  ps.execute();\n}","typeGuard":"static boolean isUsable(java.sql.Connection c) throws SQLException {\n  return c != null && !c.isClosed();\n}","tryCatchPattern":"try {\n  doWork(conn);\n} catch (SQLException e) {\n  if (\"database connection closed\".equals(e.getMessage())) {\n    conn = DriverManager.getConnection(url, props); // reopen / re-borrow\n    doWork(conn);\n  } else throw e;\n}","preventionTips":["Scope connections with try-with-resources exactly around their use, not wider","Never share a single connection across threads without a pool mediating access","Enable test-on-borrow validation in your connection pool so closed connections never reach callers"],"tags":["java","jdbc","connection-lifecycle"],"backgroundTag":"connection-closed","analyzedSha":"bad083fafbefdeae9a42ec19bdaaad8918dcf411","analyzedAt":"2026-08-16T23:12:11.798Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}