事务:完成一件事情的数据库操作语句共同构成了一个事务。
事物的基本要素:
①原子性:一组事务,要么全部成功完成,要么全部不完成
②一致性:事务开始前和结束后,数据库的完整性约束没有被破坏。如:A向B转账,那么A扣了钱,B则一定会收到。
③隔离性:每个事务独立运行。一个事务处理后的结果,影响了其他事务,那么其它事务会撤回(不完成)。事物的100%隔离,需要牺牲速度。
④持久性:事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚
1、开启事务
需要先把JDBC驱动程序的自动提交模式关闭,使用setAutoCommit()方法。
Connection conn=DriverManager.getConnection(url,username,passsword);
conn.setAutoCommit(false); //关闭了自动提交模式,同时也是开启了事务
2、提交
在mysql中,默认将每一句sql都自动提交,当我们开启了事务之后,就需要我们手动提交了。
conn.commit();//写完sql命令后提交,可以每条语句都commit,也可以多条语句一次提交,但是要注意它们的效果是不一样的
3、回滚
当有多条语句一次性提交时,我们需要考虑到其中的sql语句是否合法或正确,若其中一条不正确,其它的sql是否需要修改的一系列问题,所以我们可以手动调用事务回滚来控制sql的执行。
例1:
try{
url="jdbc:mysql://localhost:3306/数据库名; //格式
username="..."; //需完善
password="...";
Connection conn=DriverManager.getConnection(url,username,password);
conn.setAutoCommit(false);
PreparedStatement ps=conn.prepareStatement("insert into table1(column1,column2) values(1,'xx1')");
ps.executeUpdate();
ps=conn.prepareStatement("insert in table1(column1,column2) values(1,'xx1')");
ps.executeUpdate();
conn.commit();//提交事务
}catch(SQLException e){
try{
conn.rollback();//回滚事务,回滚到开始事务之前
}catch(SQLException e1){
e1.printStackTrace();
}
}
例1代码中,第二条sql命令中有语法错误,所以事务会回滚,这样的话之前的insert也会失效。通常事务回滚都会放在catch中来捕获。开启事务后,一定要跟上commit或rollback,及时释放可能锁住的数据。
例2:
try {
String url="jdbc:mysql://localhost:3306/mysql_db";
String username="root";
String password="123123";
conn=DriverManager.getConnection(url,username,password);
conn.setAutoCommit(false);
ps=conn.prepareStatement("insert into student values(4,'赵六','女',21)");
ps.executeUpdate();
conn.commit();
ps=conn.prepareStatement("insert in student values(5,'张三','男',20)");
ps.executeUpdate();
conn.commit();
} catch (SQLException e) {
try {
//事务回滚
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
finally {
try {
if(ps!=null)
ps.close();
if (conn != null)
conn.close();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
在例2代码中,在第一条sql语句执行后进行了事务提交,第二条sql语句中存在错误,也同样进行了事务提交,但是会回滚到第二条sql语句开始的时候。此例中,第一条sql语句中的内容会成功插入表中,第二条sql语句中的内容不会被成功插入表中。