tursodatabase/turso · error · SQLFeatureNotSupportedException

Savepoints are not supported by Turso

Error message

Savepoints are not supported by Turso

What it means

Turso's engine has no savepoint support, so Connection.setSavepoint() unconditionally throws SQLFeatureNotSupportedException. Savepoints would allow partial rollback inside a transaction, a feature SQLite-compatible engines exposed here do not provide through this driver.

Source

Thrown at bindings/java/src/main/java/tech/turso/jdbc4/JDBC4Connection.java:187

  @Override
  public int getHoldability() throws SQLException {
    connection.checkOpen();
    return ResultSet.CLOSE_CURSORS_AT_COMMIT;
  }

  @Override
  public void setHoldability(int holdability) throws SQLException {
    connection.checkOpen();
    if (holdability != ResultSet.CLOSE_CURSORS_AT_COMMIT) {
      throw new SQLException("turso only supports CLOSE_CURSORS_AT_COMMIT");
    }
  }

  @Override
  @SkipNullableCheck
  public Savepoint setSavepoint() throws SQLException {
    throw new SQLFeatureNotSupportedException("Savepoints are not supported by Turso");
  }

  @Override
  @SkipNullableCheck
  public Savepoint setSavepoint(String name) throws SQLException {
    throw new SQLFeatureNotSupportedException("Savepoints are not supported by Turso");
  }

  @Override
  public void rollback(Savepoint savepoint) throws SQLException {
    throw new SQLFeatureNotSupportedException("Savepoints are not supported by Turso");
  }

  @Override
  public void releaseSavepoint(Savepoint savepoint) throws SQLException {
    throw new SQLFeatureNotSupportedException("Savepoints are not supported by Turso");
  }

View on GitHub (pinned to bad083fafb)

Solutions

  1. Replace Spring's Propagation.NESTED with Propagation.REQUIRES_NEW (independent transaction) or flatten the logic into one transaction.
  2. Restructure code that needs partial rollback: validate before mutating, or sequence operations so a failure aborts the whole transaction, which is the SQLite model anyway.
  3. Catch SQLFeatureNotSupportedException if a framework probes savepoint capability at startup, and configure the framework to treat savepoints as unavailable.
  4. Remove direct setSavepoint calls; there is no driver flag to enable them.

Example fix

// before (Spring)
@Transactional(propagation = Propagation.NESTED) // internally calls setSavepoint()
public void updateInventory(Order o) { ... }

// after
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateInventory(Order o) { ... }
Defensive patterns

Strategy: try-catch

Validate before calling

if (conn.getMetaData().supportsSavepoints()) {
    Savepoint sp = conn.setSavepoint();
} else {
    // no savepoints on this driver; use whole-transaction semantics
}

Try / catch

try {
    sp = conn.setSavepoint();
} catch (SQLFeatureNotSupportedException e) {
    // savepoints unsupported: run the step as its own transaction or accept full rollback
    sp = null;
}

Prevention

When it happens

Trigger: Direct call to conn.setSavepoint(); Spring @Transactional with propagation = Propagation.NESTED, which implements nesting via savepoints; test frameworks that create savepoints to roll back test data; generic transaction-management utilities that probe savepoint support by calling it.

Common situations: Spring/Hibernate applications using PROPAGATION_NESTED business methods; porting from PostgreSQL/Oracle where nested transactions via savepoints are routine; integration-test harnesses (e.g., @Transactional test rollback with nested transactional boundaries) that rely on savepoints.

Related errors


AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16). Data as JSON: /api/errors/f1f3cc0fc16153a7. Report an issue: GitHub.