由于无效数据,有时执行诸如插入,更新或删除之类的数据库操作命令可能会引发异常。为了保护我们的应用程序数据的完整性,我们必须确保在事务失败时必须回退所有已执行的命令,以便它影响数据的状态。
在此示例中,我们使用MySQL数据库。要在MySQL中启用事务处理功能,请确保您使用的是InnoDB存储引擎来创建表。
package org.nhooo.example.jdbc; import java.sql.*; public class TransactionRollbackExample { private static final String URL = "jdbc:mysql://localhost/nhooo"; private static final String USERNAME = "root"; private static final String PASSWORD = ""; public static void main(String[] args) throws Exception { try (Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD)) { conn.setAutoCommit(false); String query = "INSERT INTO orders (username, order_date) " + "VALUES (?, ?)"; try (PreparedStatement stmt = conn.prepareStatement(query, PreparedStatement.RETURN_GENERATED_KEYS)) { stmt.setString(1, "javaduke"); stmt.setDate(2, new Date(System.currentTimeMillis())); stmt.execute(); ResultSet keys = stmt.getGeneratedKeys(); int orderId = 1; if (keys.next()) { orderId = keys.getInt(1); } // 这是一条无效的语句,将导致 // 演示回滚。 query = "INSERT INTO order_details (order_id, product_id, " + "quantity, price) VALUES (?, ?, ?, ?, ?)"; PreparedStatement detailStmt = conn.prepareStatement(query); detailStmt.setInt(1, orderId); detailStmt.setInt(2, 1); detailStmt.setInt(3, 10); detailStmt.setDouble(4, 29.99); detailStmt.execute(); // 提交事务以将其标记为成功数据库操作 conn.commit(); System.out.println("Transaction commit..."); } catch (SQLException e) { // 由于发生异常而回滚任何数据库事务 conn.rollback(); System.out.println("Transaction rollback..."); e.printStackTrace(); } } } }
Maven依赖
<!-- https://search.maven.org/remotecontent?filepath=mysql/mysql-connector-java/8.0.17/mysql-connector-java-8.0.17.jar --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.17</version> </dependency>