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);
}
}
}