JDBC支持事务自动提交机制的,只要执行一条语句,就提交一次事务。
下边模拟一个根据名称修改密码的例子,假设密码必须同时修改了2次,才能修改成功,在第一次提交之后,我们故意抛出了一个异常:
package com;
import java.sql.*;
public class Test {
public static void main(String[] args) {
Connection conne = null;
PreparedStatement sta = null;
try {
// 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 获取连接 - 连接mysql数据库
try {
conne = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/java_pro?useUnicode=true&characterEncoding=utf8", "root", "lvxingchen"); // 获取连接对象
// 第一次提交
String sql = "update java_pro set password = ? where name = ?"; // 创建sql模板,? 表示占位符
sta = conne.prepareStatement(sql);// prepareStatement 预编译sql语句,防止sql注入
sta.setString(1, "321"); // 替换?
sta.setString(2, "星辰");
int count = sta.executeUpdate();
System.out.println(count);
// 故意抛出一个异常
String s = null;
s.toString()
// 第二次提交
String sql1 = "update java_pro set password = ? where name = ?"; // 创建sql模板,? 表示占位符
sta = conne.prepareStatement(sql1);// prepareStatement 预编译sql语句,防止sql注入
sta.setString(1, "789"); // 替换?
sta.setString(2, "星辰");
int count1 = sta.executeUpdate();
System.out.println(count1);
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
// 在finally中释放资源,并且按顺序依次关闭
try {
if(sta != null) {
sta.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
if(conne != null) {
conne.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
结果第一次修改的数据被提交了,由于执行第二次之前,出现错误,所以第二次修改未生效,这也是JDBC默认事务的执行方式。
我了防止这样的错误发生,我们需要手动关闭自动提交事务机制,下边修改上边代码:
主要是三行代码:
conne.setAutoCommit(false) ; 取消自动提交机制
conne.commit() ; 提交
conne.rollback() ; 手动回滚
package com;
import java.sql.*;
public class Test {
public static void main(String[] args) {
Connection conne = null;
PreparedStatement sta = null;
try {
// 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 获取连接 - 连接mysql数据库
try {
conne = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/java_pro?useUnicode=true&characterEncoding=utf8", "root", "lvxingchen"); // 获取连接对象
// 关闭JDBC自动自交事务机制,我们手动来提交
conne.setAutoCommit(false);
// 第一次提交
// 省略SQL语句 ···· ····
// 第二次提交
// 省略SQL语句 ···· ····
// 最后SQL语句都执行完毕,我们手动提交事务
conne.commit();
} catch (SQLException throwables) {
if(conne != null) {
try {
conne.rollback(); // 手动回滚
} catch (SQLException e) {
e.printStackTrace();
}
}
throwables.printStackTrace();
} finally {
// 释放资源省略
}
} catch (ClassNotFoundException e) {
}
}
}
在IDEA中,批量编辑的小技巧
Alt + 鼠标拖动