-
JDBC事务管理:Connection接口中定义了3个对应方法
-
setAutoCommit(boolean autoCommit):true为自动提交事务;false为手动提交,即开启事务
-
commit():commit()方法一定要在try代码块中的最后一行,否则commit后面任何错误跳到catch里面之后执行rollback都无效了
-
rollback()
-
正常的执行事务的方法:
public class JDBCDemo {
public static void main(String[] args) throws Exception {
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//连接
String url = "jdbc:mysql://127.0.0.1:3306/db1?useSSL=false";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, username, password);
//定义sql
String sql1 = "insert into stu(name, id) values ('zhangsan', 3);";
String sql2 = "insert into stu(name, id) values ('lisi', 4);";
//获取执行sql的对象
Statement stmt = conn.createStatement();
try{
//相当于开启事务
conn.setAutoCommit(false);
//执行两次事务
stmt.executeUpdate(sql1);
stmt.executeUpdate(sql2);
//事务提交
conn.commit();
}catch (Exception e){
//如果出错就回滚
conn.rollback();
e.printStackTrace();
}
//释放资源
stmt.close();
conn.close();
}
}
setAutoCommit(false)的意思是不自动提交事务
在编写代码的时候,如果不使用conn.setAutoCommit(false)语句,程序会默认每一条语句都是独立的事务,每执行一条语句之后都会默认提交,这时候如果写roolback()和commit()都会报错
这里我们使用try catch的方法实现事务的提交或回滚,这里的conn.commit()一定是在try代码块的最后提交才可以,否则commit之后的代码将不会被提交。
例如
try{
//相当于开启事务
conn.setAutoCommit(false);
stmt.executeUpdate(sql1);
//提交事务
conn.commit();
stmt.executeUpdate(sql2);
}catch (Exception e){
conn.rollback();
e.printStackTrace();
}
此时的sql2并没有被执行,实际上sql2在执行之后被写进了缓冲区,因为没有commit操作,所以没有写进磁盘里,没有真正改变数据库。缓冲区在程序结束之后随着两个close()语句被释放,所以相当于sql2没有被执行。
下面展示程序出错之后的回滚
try{
//相当于开启事务
conn.setAutoCommit(false);
stmt.executeUpdate(sql1);
//提交事务
conn.commit();
int i = 1/ 0;
stmt.executeUpdate(sql2);
}catch (Exception e){
conn.rollback();
e.printStackTrace();
}
这里在执行到int i = 1/ 0之前都是正确的,但是sql1在程序出错之前已经被提交了,所以catch语句中的rollback方法虽然被执行了,但是也不会撤销sql1语句。所以commit()方法记得放到try代码块的最后!