package com.java; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.junit.Test; public class TransactionTest { /** * 测试事务的隔离级别 在 JDBC 中,可以用 Connection 的 setTransactionIsolation() * 方法来设置事务的隔离级别 */ @Test public void testTransactionIsolationUpdate() { Dao dao = new Dao(); Connection connection = null; try { connection = JDBCTools.getConnection(); // 设置不自动提交 connection.setAutoCommit(false); String sql = "UPDATE user SET balance = balance - 500 WHERE id = 1"; dao.update(connection, sql); connection.commit();//加一个断点,使程序到这儿暂停,测试其他线程读取到的是否是未提交的数据 } catch (Exception e) { e.printStackTrace(); } finally { } } @Test public void testTransactionIsolationRead() { String sql = "SELECT balance FROM user WHERE id = 1"; Integer balance = getForValue(sql); System.out.println(balance); } // 返回某条记录的某一个字段的值 或 一个统计的值(一共有多少条记录等.) public <E> E getForValue(String sql, Object... args) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { // 1.得到结果集 connection = JDBCTools.getConnection(); /* * 可以在 cmd 中设置mySql的隔离级别 * ① mysql -uroot -p123456 * 查看当前 mySql 的隔离级别 * ② SELECT @@tx_isolation; * 设置当前 mySql 的隔离级别 * ③ set transaction isolation level read committed; * 设置数据库系统全局的隔离级别 * ④ set global transaction isolation level read committed; */ // 查看mySql 默认的隔离级别 System.out.println(connection.getTransactionIsolation()); // 读取未提交的数据 // connection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED); // 读取已提交的数据 connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); preparedStatement = connection.prepareStatement(sql); for (int i = 0; i < args.length; i++) { preparedStatement.setObject(i + 1, args[i]); } resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { return (E) resultSet.getObject(1); } } catch (Exception e) { e.printStackTrace(); } return null; } /** * Tom 给 Jerry 汇款500 元。 * * 关于事务: 1. 如果多个操作,每个操作使用的是单独的链接,则无法保证事务. 2. 具体步骤: 1). 事务操作开始前,开始事务: 取消 * Connection 的默认提交行为. connection.setAutoCommit(false); 2). * 如果事务的操作都成功,则提交事务: connection.commit(); 3). 回滚事务: 若出现异常,则在 catch 块中回滚事务 * connection.roolback(); */ @Test public void testTransaction() { Dao dao = new Dao(); Connection connection = null; try { connection = JDBCTools.getConnection(); // 开始事务: 取消默认提交 connection.setAutoCommit(false); String sql = "UPDATE user SET balance = balance - 500 WHERE id = 1"; dao.update(connection, sql); // 增加一个异常,看事务是否回滚 int i = 10 / 0; System.out.println(i); sql = "UPDATE user SET balance = balance + 500 WHERE id = 2"; dao.update(connection, sql); // 提交事务 connection.commit(); } catch (Exception e) { e.printStackTrace(); try { // 回滚事务 connection.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } } finally { JDBCTools.release(null, null, connection); } } }