Learn how to group database operations into atomic units for reliability
Table of Contents
What Are Transactions?
A transaction is a sequence of database operations (e.g., inserts, updates) treated as a single logical unit. Transactions ensure ACID properties:
- Atomicity: All operations succeed or fail together.
- Consistency: Data remains valid before and after the transaction.
- Isolation: Concurrent transactions don’t interfere.
- Durability: Changes persist after a transaction commits.
Real-World Example:
Imagine transferring $100 between two bank accounts:
- Deduct $100 from Account A.
- Add $100 to Account B.
If either step fails, both should roll back to avoid inconsistency.
Default Behavior: Auto-Commit Mode
By default, JDBC uses auto-commit mode, where every SQL statement is treated as a separate transaction. This is risky for multi-step operations:
// Without transactions (risky!)
statement.executeUpdate("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
statement.executeUpdate("UPDATE accounts SET balance = balance + 100 WHERE id = 2");
// If the second query fails, $100 is lost!
Managing Transactions in JDBC
Step 1: Disable Auto-Commit
Connection conn = DriverManager.getConnection(url, user, password);
conn.setAutoCommit(false); // Transactions now manual
Step 2: Group Operations
Execute all queries as part of a single transaction:
try {
// Transfer $100 from Account 1 to 2
PreparedStatement deduct = conn.prepareStatement(
"UPDATE accounts SET balance = balance - 100 WHERE id = ?"
);
deduct.setInt(1, 1);
deduct.executeUpdate();
PreparedStatement add = conn.prepareStatement(
"UPDATE accounts SET balance = balance + 100 WHERE id = ?"
);
add.setInt(1, 2);
add.executeUpdate();
// Commit if both succeed
conn.commit();
} catch (SQLException e) {
conn.rollback(); // Undo all changes on failure
}
Step 3: Handle Commit/Rollback
- Commit: Save changes permanently with
conn.commit()
. - Rollback: Undo changes with
conn.rollback()
.
Transaction Isolation Levels
Isolation levels control how transactions interact with concurrent operations. Common levels include:
Level | Description |
---|---|
READ_UNCOMMITTED | Allows reading uncommitted changes (risky). |
READ_COMMITTED | Reads only committed data (default in most databases). |
REPEATABLE_READ | Ensures consistent reads during a transaction. |
SERIALIZABLE | Highest isolation (prevents concurrency issues). |
Setting Isolation Level
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
Best Practices
- Keep Transactions Short: Avoid long-running transactions to reduce locking.
- Always Handle Exceptions: Rollback on errors to prevent partial updates.
- Use Savepoints (Advanced): Create checkpoints within transactions for partial rollbacks.
Savepoint savepoint = conn.setSavepoint("SAVEPOINT_1");
// ...
conn.rollback(savepoint); // Rollback to savepoint
Full Example: Bank Transfer
public class BankTransfer {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/bank";
String user = "root";
String password = "root123";
try (Connection conn = DriverManager.getConnection(url, user, password)) {
conn.setAutoCommit(false); // Start transaction
try {
// Deduct from Account 1
PreparedStatement deduct = conn.prepareStatement(
"UPDATE accounts SET balance = balance - ? WHERE id = ?"
);
deduct.setDouble(1, 100.0);
deduct.setInt(2, 1);
deduct.executeUpdate();
// Add to Account 2
PreparedStatement add = conn.prepareStatement(
"UPDATE accounts SET balance = balance + ? WHERE id = ?"
);
add.setDouble(1, 100.0);
add.setInt(2, 2);
add.executeUpdate();
conn.commit(); // Commit transaction
System.out.println("Transfer successful!");
} catch (SQLException e) {
conn.rollback(); // Rollback on error
System.err.println("Transfer failed: " + e.getMessage());
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Common Errors
Error | Solution |
---|---|
Auto-commit mode is enabled | Disable with setAutoCommit(false) . |
Transaction rolled back | Handle exceptions and retry logic. |
Lock wait timeout exceeded | Optimize transaction duration. |
Summary
- Transactions ensure atomicity and consistency for multi-step operations.
- Use
setAutoCommit(false)
,commit()
, androllback()
to manage transactions. - Choose isolation levels based on concurrency needs.
Next Up: JDBC Best Practices – Learn how to write efficient, secure database code!