Tom给jerry汇款500元
1、如果多个操作,每个操作使用的是自己的单独的连接,则无法保证事务
2、具体步骤:
1>事务开始操作前,开始事务:取消Connection的默认提交行为
2>如果事务的操作都成功,都提交事务
3>回滚事务:若出现异常,则在catch块中回滚事务;
3、模板 try {
//开始事务:取消默认提交(默认自动提交) con.setAutoCommit(false);
//...
//提交事务 con.commit();
} catch (Exception e) {
//...
//如果出现异常就回滚事
try {
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
@Test
public void testTransaction() {
Connection con = null;
try {
con = JDBCTools.getConnection();
System.out.println("默认事务:" + con.getAutoCommit());
// 开始事务:取消默认提交(默认自动提交)
con.setAutoCommit(false);
String sql = "update users set balance=balance-500 where id=1";
update(con, sql);
int i = 10 / 0;
sql = "update users set balance=balance+500 where id=2";
update(con, sql);
// 提交事务
con.commit();
} catch (Exception e) {
// 如果出现异常就回滚事务
try {
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
JDBCTools.release(null, null, con);
}
}
设置事务的隔离级别
@Test
public void testTransactionIsolationRead() {
String sql = "select balance from users where id=1";
Integer balance=getForValue(sql);
System.out.println("balance="+balance);
}
/*
* 测试事务的隔离级别 在JDBC程序中可以通过Connection的setTransactionIsolation()方法 来设置事务的隔离级别
*/
@Test
public void testTransactionIsolationUpdate() {
Connection con = null;
try {
con = JDBCTools.getConnection();
// 开始事务:取消默认提交(默认自动提交)
con.setAutoCommit(false);
String sql = "update users set balance=balance-500 where id=1";
update(con,sql);
con.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
// 返回某个对象的属性值
@SuppressWarnings("unchecked")
public <E> E getForValue(String sql, Object... args) {
// 1、得到结果集:该结果集应该只有一行且只有一列
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = JDBCTools.getConnection();
//con.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
ps = con.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
rs = ps.executeQuery();
if (rs.next()) {
return (E) rs.getObject(1);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCTools.release(rs, ps, con);
}
// 2、取得结果集的
return null;
}
更新后的JDBCTools.java工具类如下:
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/*
* JDBC工具类
* */
public class JDBCTools {
// 提交事务
public static void commit(Connection con) {
if (con != null) {
try {
con.commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//回滚事务
public static void rollback(Connection con) {
if (con != null) {
try {
con.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//开始事务
public static void beginTx(Connection con) {
if (con != null) {
try {
con.setAutoCommit(false);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/*
* 执行SQL的方法 insert,update,delete
*/
public static void update(String sql, Object... args) {
Connection conn = null;
PreparedStatement ps = null;
try {
/*
* 1、获取Connection连接 2、获取Statement 3、SQL语句 4、关闭数据库连接
*
*/
conn = getConnection();
ps = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
release(null, ps, conn);
}
}
public static Connection getConnection() throws Exception {
String driverClass = null;
String jdbcUrl = null;
String user = null;
String password = null;
// 读取类路径下的jdbc.properties文件
InputStream in = JDBCTools.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties properties = new Properties();
properties.load(in);
driverClass = properties.getProperty("driver");
jdbcUrl = properties.getProperty("jdbcUrl");
user = properties.getProperty("user");
password = properties.getProperty("password");
// 加载数据库驱动程序
Class.forName(driverClass);
// 通过DriverManager的getConnection()方法获取数据库连接
Connection connection = DriverManager.getConnection(jdbcUrl, user, password);
return connection;
}
public static void release(ResultSet rs, Statement st, Connection conn) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (st != null) {
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}