Unravel › Java concepts › JDBC and SQL mappers
JDBC transactions and batching
By default each JDBC statement commits on its own.
Learn these first
At a glance
A bank transfer written on a slip: take money out and put it in must both happen or neither.
- 1conn.setAutoCommit(false); try { ps1.executeUpdate(); ps2.executeUpdate(); conn.commit(); } catch (SQLException e) { conn.rollback(); throw e; }Restore auto-commit or close the connection afterwards, because pools reuse it.
- 2Batch: for (row : rows) { ps.setLong(1, row.id); ps.addBatch(); } int[] counts = ps.executeBatch(); often 10 to 100 times faster than single insertsCommit every few thousand rows for huge loads.
- 3conn.setTransactionIsolation(...) selects what a transaction can see of others: READ_COMMITTED (typical), REPEATABLE_READ, SERIALIZABLEA Savepoint allows a partial rollback.
- 4prepareStatement(sql, Statement.RETURN_GENERATED_KEYS) and ps.getGeneratedKeys() return database-generated ids
- Hand-written commit/rollback code is easy to get wrong (missing rollback on an exception path, leaked connection state)
- Long transactions hold locks and block others, and increase deadlock chances
- Auto-commit mode wraps each statement in its own transaction on the server
import java.sql.*;import java.util.List;public class Loader { static void insertAll(Connection conn, List<String> names) throws SQLException { boolean old = conn.getAutoCommit(); conn.setAutoCommit(false); try (PreparedStatement ps = conn.prepareStatement("INSERT INTO people(name) VALUES (?)")) { for (String n : names) { ps.setString(1, n); ps.addBatch(); } ps.executeBatch(); conn.commit(); } catch (SQLException e) { conn.rollback(); throw e; } finally { conn.setAutoCommit(old); } }}- line 6 uses setAutoCommit, the core of JDBC transactions and batching
- line 8 uses addBatch, the core of JDBC transactions and batching
- line 9 uses executeBatch, the core of JDBC transactions and batching
- line 10 uses commit, the core of JDBC transactions and batching
- line 12 uses rollback, the core of JDBC transactions and batching
- line 15 uses setAutoCommit, the core of JDBC transactions and batching
Read the full explanation (about 1 min)
By default each JDBC statement commits on its own. A transaction groups several statements so they succeed or fail together: setAutoCommit(false), run the statements, then commit() or rollback(). Batching sends many rows in one round trip.
A mental model
A bank transfer written on a slip: take money out and put it in must both happen or neither. Batching is posting a whole bag of mail at once instead of walking to the post box for each letter.
How it works
conn.setAutoCommit(false); try { ps1.executeUpdate(); ps2.executeUpdate(); conn.commit(); } catch (SQLException e) { conn.rollback(); throw e; }. Restore auto-commit or close the connection afterwards, because pools reuse it.
Batch: for (row : rows) { ps.setLong(1, row.id); ps.addBatch(); } int[] counts = ps.executeBatch(); often 10 to 100 times faster than single inserts. Commit every few thousand rows for huge loads.
conn.setTransactionIsolation(...) selects what a transaction can see of others: READ_COMMITTED (typical), REPEATABLE_READ, SERIALIZABLE. A Savepoint allows a partial rollback.
prepareStatement(sql, Statement.RETURN_GENERATED_KEYS) and ps.getGeneratedKeys() return database-generated ids.
Going deeper
Hand-written commit/rollback code is easy to get wrong (missing rollback on an exception path, leaked connection state). That is why @Transactional in Spring and JPA exist: they apply this try/catch for you.
Long transactions hold locks and block others, and increase deadlock chances. Keep them short and never include remote calls inside.
Batch settings matter: some drivers need rewriteBatchedStatements=true (MySQL) or reWriteBatchedInserts=true (PostgreSQL) to really send one statement.
Under the hood
Auto-commit mode wraps each statement in its own transaction on the server. With it off the driver sends BEGIN implicitly, and commit()/rollback() sends the matching command; pools reset the flag when the connection returns.
Common mistakes
- No rollback on failure.
- Returning a connection to the pool with auto-commit left off.
- Single-row inserts in a loop.
- Remote calls inside a database transaction.
How Unravel recognises it
When you paste code, Unravel looks for these signs of jdbc transactions and batching. Spotting them yourself is a good habit when you read unfamiliar code:
- Types:
Savepoint - Method calls:
setAutoCommit()commit()rollback()addBatch()executeBatch()setSavepoint()setTransactionIsolation()getGeneratedKeys()setFetchSize()executeLargeBatch() - Constants:
Connection.TRANSACTION_SERIALIZABLEStatement.RETURN_GENERATED_KEYS
Part of a learning path
- JDBC and everyday libraries · previous: JDBC connections, DataSource and pools · next: ResultSet and mapping rows to objects
Related concepts
Frequently asked questions
What is JDBC transactions and batching?
By default each JDBC statement commits on its own. A transaction groups several statements so they succeed or fail together: setAutoCommit(false), run the statements, then commit() or rollback(). Batching sends many rows in one round trip.
What are the most common mistakes with JDBC transactions and batching?
No rollback on failure. Returning a connection to the pool with auto-commit left off. Single-row inserts in a loop. Remote calls inside a database transaction.
How can I see JDBC transactions and batching in real code?
Paste your own Java into Unravel and it will point out where jdbc transactions and batching appears, explain how it works at the detail level you choose, and draw the flow of the code around it.