需要掌握:数据库事务的4个特性(ACID)
应用场景
- 在一个操作中,执行多次 增、删、改 时,需要使用事务
- 在某些企业,只要执行 增、删、改 操作,就需要使用事务
- 使用某些框架时,只要执行 增、删、改 操作,就需要使用事务,如:hibernate
步骤
第一步:设置 非自动提交
数据库连接 默认是 自动提交 的,意思是:只要执行 增、删、改 操作,就 立即 自动 保存 到数据库中
而我们的想法是:需要提交时,才会提交,所以需要设置数据库连接为 非自动提交,如下:
conn.setAutoCommit(false);
第二步:提交事务、回滚事务
编写 try...catch... 代码块,在 try 代码块内,编写 增、删、改 数据库操作,如下:
try{
//增删改数据库操作
.....
.....
//当上面操作没有报错时,提交事务,此时才会保存到数据库
//执行conn.setAutoCommit(false)后,连接为非自动提交,那么不执行commit(),增删改操作不会保存到数据库中
conn.commit();
}catch(Exception e){
//如果报错,就回滚,数据恢复到初始值
conn.rollback();
}
注意
- 数据库连接为 非自动提交 时,才能执行 提交事务、回滚事务。
- 如果是 自动提交,执行
commit()、rollback()会报错
完善银行转账
原银行转换见 数据库事务-银行转账问题
导包:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
java代码:
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://127.0.0.1:3308/scott?useSSL=false&useUnicode=true&characterEncoding=utf-8";
Connection conn = DriverManager.getConnection(url,
"root",//用户名
"");//密码
//===关键,设置不自动提交==============
conn.setAutoCommit(false);
try{
//从马云账户减掉100
String sql="update account set money=money-? where aid=?";
PreparedStatement pstm=conn.prepareStatement(sql);
pstm.setInt(1, 100);
pstm.setInt(2,1);
pstm.executeUpdate();
pstm.close();
//======关键,演示一个错误==============
/*
* 运行该行代码时会报错,不再执行下面代码
* 然后执行catch部分,会执行 rollback(),数据恢复到初始值
* 如果注释掉该行代码,不会报错,会执行 commit(),就提交到数据库
*/
int i=1/0;
//给李雷账户加上100
String sql2="update account set money=money+? where aid=?";
PreparedStatement pstm2=conn.prepareStatement(sql2);
pstm2.setInt(1, 100);
pstm2.setInt(2,2);
pstm2.executeUpdate();
pstm2.close();
//====关键:上面代码都执行成功,就提交事务,增删改操作才会保存到数据库
//====注意: 数据库连接为 非自动提交 时,不执行此代码,不会保存到数据库
conn.commit();
}catch(Exception e){
//====关键:报错后,就回滚事务,数据恢复到初始值
conn.rollback();
e.printStackTrace();
}
conn.close();