1、如何实现事务
如果现在希望对 A 表和 B 表同时删除某一个 id 号的记录,使这两个sql操作组成一个事务。(成功则同时成功,否则都失败)
注意:如果 B 表 建立了引用 A 表的id外键,并指定为 on delete cascade, 此时在删除 A 表中的id号时,会自动把对应的 B 表中的id号记录删除。
实践:同时删除course和teacher表中id号为5的记录;
package com.dgd.test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; public class Test01 { public static void main(String[] args) throws ClassNotFoundException, SQLException { //①注册驱动 Class.forName("com.mysql.cj.jdbc.Driver"); //url String url="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT"; //②获取连接 Connection conn = DriverManager.getConnection(url, "root", "123456"); System.out.println(conn.getClass()); //③*****设置手动提交事务 conn.setAutoCommit(false); //编写sql语句 1 String sql1="DELETE FROM course where id=?"; //编写sql语句 2 String sql2="DELETE FROM teacher where id=?"; //④创建 PreparedStatement 对象 PreparedStatement s1 = conn.prepareStatement(sql1); PreparedStatement s2 = conn.prepareStatement(sql2); //设置 ? 值 s1.setObject(1,"5"); s2.setObject(1,"5"); boolean flag1=true;// boolean flag2=true;// sql执行的标志位 try { //⑥执行sql语句 int len1=s1.executeUpdate(); System.out.println(len1>0?"删除course表成功":"删除course表失败"); if(len1<0) { flag1=false; } if(flag1==true) { int len2=s2.executeUpdate(); System.out.println(len2>0?"删除teacher表成功":"删除teacher表失败"); if(len2<0) { flag2=false; } } if(flag1==true && flag2==true) conn.commit(); else conn.rollback(); } catch (SQLException e) { System.out.println("发生异常"); conn.rollback(); } //⑦关闭资源 s1.close(); s2.close(); conn.setAutoCommit(true); //⑧还原 conn.close(); } }
当故意估计修改错 sql 语句(删除id 4)时,判断是否会回滚;
//编写sql语句 1 String sql1="DELETE FROM course where id=?"; //编写sql语句 2 String sql2="DELETE FROM teacher id=?"; //④创建 PreparedStatement 对象 PreparedStatement s1 = conn.prepareStatement(sql1); PreparedStatement s2 = conn.prepareStatement(sql2); //设置 ? 值 s1.setObject(1,"4"); s2.setObject(1,"4");
虽然显示course表删除成功,但是实际上回滚,并没有实际提交;
course表中仍然存在id: 4