JDBC
jdbc4TransactionsAndBatch
- Path
- pkg11jdbc/jdbc4TransactionsAndBatch.java
- Package
- pkg11jdbc
- Study order
- 4
- Run
- Runs without a driver. The database demo needs an optional JDBC driver.
- Command
- java pkg11jdbc/jdbc4TransactionsAndBatch.java
- Dependencies
- Optional in-memory JDBC driver (H2, SQLite, or HSQLDB)
There is no in-browser runner. This is the file from the curriculum, unchanged.
1package pkg11jdbc;2 3import java.sql.Connection;4import java.sql.DriverManager;5import java.sql.PreparedStatement;6import java.sql.ResultSet;7import java.sql.SQLException;8import java.sql.Statement;9 10/*11 * jdbc4TransactionsAndBatch.java12 * ------------------------------13 * Transactions (commit/rollback) and batch updates for correctness & speed.14 *15 * DEFINITION:16 * A transaction groups statements into an all-or-nothing unit (ACID). Batching17 * sends many statements to the DB in one round trip for throughput.18 *19 * KEY POINTS:20 * - setAutoCommit(false) starts manual transaction control.21 * - commit() makes changes permanent; rollback() undoes them on error.22 * - Savepoints allow partial rollback within a transaction.23 * - addBatch()/executeBatch() drastically reduce per-statement overhead.24 *25 * Runs for real with an in-memory DB driver; otherwise prints guidance.26 */27public class jdbc4TransactionsAndBatch {28 29 static Connection tryConnect() {30 for (String url : new String[]{"jdbc:h2:mem:demo;DB_CLOSE_DELAY=-1",31 "jdbc:sqlite::memory:", "jdbc:hsqldb:mem:demo"}) {32 try { return DriverManager.getConnection(url); } catch (SQLException ignored) {}33 }34 return null;35 }36 37 public static void main(String[] args) throws SQLException {38 Connection conn = tryConnect();39 if (conn == null) {40 System.out.println("No in-memory DB driver found. This demo would:");41 System.out.println(" 1. setAutoCommit(false)");42 System.out.println(" 2. batch-insert 5 rows, then commit()");43 System.out.println(" 3. attempt a bad transfer and rollback() to keep balances consistent");44 System.out.println("Add h2.jar to the classpath to run it for real.");45 return;46 }47 48 try (conn) {49 try (Statement st = conn.createStatement()) {50 st.execute("CREATE TABLE account (id INT PRIMARY KEY, balance INT)");51 }52 53 // BATCH insert inside a transaction54 conn.setAutoCommit(false);55 try (PreparedStatement ps = conn.prepareStatement("INSERT INTO account VALUES (?, ?)")) {56 for (int i = 1; i <= 5; i++) {57 ps.setInt(1, i);58 ps.setInt(2, 100);59 ps.addBatch(); // queue, don't send yet60 }61 int[] counts = ps.executeBatch(); // one round trip62 conn.commit();63 System.out.println("Batch inserted " + counts.length + " rows, committed.");64 }65 66 // A transfer that fails — demonstrate rollback keeps data consistent67 try {68 try (PreparedStatement debit = conn.prepareStatement(69 "UPDATE account SET balance = balance - 50 WHERE id = 1");70 PreparedStatement credit = conn.prepareStatement(71 "UPDATE account SET balance = balance + 50 WHERE id = 999")) { // no such row72 debit.executeUpdate();73 int credited = credit.executeUpdate();74 if (credited == 0) throw new SQLException("destination account missing");75 conn.commit();76 }77 } catch (SQLException e) {78 conn.rollback();79 System.out.println("Transfer failed -> rolled back: " + e.getMessage());80 }81 82 // Verify account 1 still has 100 (debit undone)83 try (Statement st = conn.createStatement();84 ResultSet rs = st.executeQuery("SELECT balance FROM account WHERE id = 1")) {85 if (rs.next()) System.out.println("Account 1 balance after rollback: " + rs.getInt(1));86 }87 }88 }89}