A JDBC savepoint marks a position inside a caller-owned transaction. Rolling back to it undoes later database changes while retaining earlier uncommitted changes.
Java JDBC savepoints: roll back one optional step inside a transaction
Operational contract
This method requires auto-commit to be off and assumes the caller owns the transaction. It creates a savepoint immediately before an optional audit insert. If the insert fails, it rolls back to the savepoint and rethrows the original SQLException. The caller then decides whether the earlier shipment work may be committed or whether the entire transaction must be rolled back. Some drivers or transaction managers do not support savepoints; detect support before making this policy mandatory. This helper never commits, changes isolation, or closes the connection.
Failure case
A shipment update succeeds, then an optional audit row conflicts with an existing key. The helper rolls back only its attempted audit insert. The outer service can decide whether a missing audit record is acceptable; it must not blindly commit after every SQL failure, especially if the connection itself is unusable.
Java code
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Savepoint;
public class OptionalShipmentAudit {
public static void insert(Connection connection, long shipmentId) throws SQLException {
if (connection.getAutoCommit()) throw new IllegalStateException("Transaction required");
Savepoint beforeAudit = connection.setSavepoint();
try (PreparedStatement statement = connection.prepareStatement(
"INSERT INTO shipment_audit (shipment_id, event_code) VALUES (?, ?)")) {
statement.setLong(1, shipmentId);
statement.setString(2, "REVIEW-47");
if (statement.executeUpdate() != 1) throw new SQLException("Audit row not inserted");
} catch (SQLException failure) {
try { connection.rollback(beforeAudit); }
catch (SQLException rollbackFailure) { failure.addSuppressed(rollbackFailure); }
throw failure;
}
}
}Performance and ownership cost
Creating and rolling back a savepoint involve driver and database round trips or local transaction bookkeeping. The Java method retains O(1) application state. Database undo work depends on changes after the savepoint; it is not free merely because the Java code is short.
Common Mistakes
- Do not create a savepoint while auto-commit is enabled.
- Do not treat a rollback-to-savepoint failure as permission to commit.
- Do not assume every driver or managed transaction supports savepoints.
Connected lessons
- Java JDBC transactions: atomic updates and rollback
- Java JDBC isolation: uncommitted writes and separate sessions
- Java DatabaseMetaData: check features before depending on them
- Java JDBC query timeout: bound a statement without claiming a whole-request deadline
- Java JDBC read-only mode: use the hint without treating it as authorization
- Java JDBC boundary contracts quiz
- Advanced Java
