JDBC事务管理
首先创建配置文件
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/test user=root password=123456
创建工具类
import java.io.FileReader; import java.net.URL; import java.sql.*; import java.util.Properties; /** *工具类 */ public class JDBCUtils { private static String url; private static String user; private static String password; private static String driver; private JDBCUtils() {}; /** * 文件的读取只需要读一次即可拿到这些值,使用静态代码块 */ static { // 读取资源文件 try { // 创建properties集合类 Properties pro = new Properties(); // 获取src路径下的文件的方式,ClassLoader类加载器,随便用一个src下的类的字节码文件 ClassLoader classLoader = JDBCUtils.class.getClassLoader(); // URL表示一个统一资源标识符(统一资源定位符),这个统一资源定位符可以定位一个文件的绝对路径 URL resource = classLoader.getResource("jdbc.properties"); // 获取该文件的绝对路径 String path = resource.getPath(); // 加载文件 pro.load(new FileReader(path)); // 获取数据,赋值 url = pro.getProperty("url"); user = pro.getProperty("user"); password = pro.getProperty("password"); driver = pro.getProperty("driver"); // 注册驱动 Class.forName(driver); } catch (Exception e) { e.printStackTrace(); } } /** * 获取连接对象 * 需求:不想传递参数(麻烦,还没有源代码简洁),还得保证工具类的通用性 * 解决:使用配置文件*/ public static Connection getConnection() throws Exception { return DriverManager.getConnection(url, user, password); } /** * 释放资源 * @param statement sql执行语句对象 * @param connection 连接对象 */ public static void close(Statement statement, Connection connection) { close(null, statement, connection); } /** * 释放资源 * @param resultSet 结果集对象 * @param statement sql执行语句对象 * @param connection 连接对象 */ public static void close(ResultSet resultSet, Statement statement, Connection connection) { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } else if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
-
使用Connection对象来管理事务
-
开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
-
提交事务:commit()
-
回滚事务:rollback()
-
-
在执行sql语句之前开启事务connection.setAutoCommit(false);,出现异常就在catch代码块中使用connection.rollback();回滚事务,正常结束就在try代码块中使用connection.commit();提交事务。
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class JdbcTransferAccounts { public static void main(String[] args) { Connection connection = null; PreparedStatement prepared1 = null; PreparedStatement prepared2 = null; try { // 使用我们自己创建的工具类获取连接 connection = JDBCUtils.getConnection(); // 开启事务 connection.setAutoCommit(false); // 定义sql语句 String sql1 = "update account set balance = balance - ? where id = ?"; String sql2 = "update account set balance = balance + ? where id = ?"; // 获取执行sql对象 prepared1 = connection.prepareStatement(sql1); prepared2 = connection.prepareStatement(sql2); // 设置参数 prepared1.setDouble(1, 5000); prepared1.setInt(2, 1); prepared2.setDouble(1, 5000); prepared2.setInt(2, 2); // 执行sql prepared1.executeUpdate(); // 手动制造一个异常,使prepared2.executeUpdate();无法执行,方便测试观察事务 // int a = 3 / 0; prepared2.executeUpdate(); // 提交事务 connection.commit(); } catch (Exception e) { try { // 出现异常,回滚事务 if (connection != null) connection.rollback(); } catch (Exception ex) { ex.printStackTrace(); } e.printStackTrace(); } finally { // 释放资源 JDBCUtils.close(prepared1, connection); JDBCUtils.close(prepared2, null); } } }

浙公网安备 33010602011771号