事务控制
所有的SQL数据库都有一个非常重要的技术亮点:拥有完善的事务,实际上所谓的事务本质上来讲就是若干个数据更新操作要么一起成功,要么一起失败。
事务本身具有:原子性(Atomicity )、一致性(Consistency )、隔离性或独立性( Isolation)、持久性(Durabilily)四个特征,以上的四个特征,也被称为ACID特征。
官方解释:
在JDBC的开发过程之中,对于事务的控制所有的操作的形式都是在Connection接口中定义的,如果没有任何的配置,那么我们的程序默认情况下是不会开启事务的。
范例:观察一组错误的操作
首先将数据表中的数据删除,确定里面无数据。
import java.sql.*;
import java.util.Arrays;
public class PreparedStatmentDemo {
public static final String DRIVER = "com.mysql.cj.jdbc.Driver"; //数据库的驱动程序
public static final String URL="jdbc:mysql://localhost:3306/yootk"; //连接地址
public static final String USER = "root"; //用户名
public static final String PASSWORD = "mysqladmin"; //密码
public static void main(String[] args) throws Exception{
long currentPage = 1; //当前所在页
int lineSize = 2; //每页获取的数据行
String column = "name"; //查询列名称,而不是数据
String keyword = "李"; //模糊关键字
Class.forName(DRIVER); //将数据的驱动程序加载到容器内部
Connection connection = DriverManager.getConnection(URL,USER,PASSWORD); //获取数据库的连接
Statement statement = connection.createStatement();
//追加批处理
statement.addBatch("INSERT INTO user (name) VALUE ('张三')");
statement.addBatch("INSERT INTO user (name) VALUE ('李四')");
//把这四条数据当成一个事务,这里故意将数据无法执行。
statement.addBatch("INSERT INTO user (name) VALUE ('王五'')");
statement.addBatch("INSERT INTO user (name) VALUE ('赵六')");
int[] result = statement.executeBatch(); //执行批处理
System.out.println("【批处理结果】:"+ Arrays.toString(result));
connection.close(); //关闭连接
}
}
Exception in thread "main" java.sql.BatchUpdateException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''王五'')' at line 1
Caused by: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''王五'')' at line 1
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.StatementImpl.executeUpdateInternal(StatementImpl.java:1333)
at com.mysql.cj.jdbc.StatementImpl.executeBatchInternal(StatementImpl.java:857)
... 2 more程序报错
查看表中数据:
此时在追加第三条数据的时候就已经产生了错误,所以按照正常的设计结构来说,这个时候的错误应该将所有的更新操作进行全部的回滚处理。而之所以没有回滚是因为默认情况下的JDBC连接采用自动事务处理模式:自动提交更新。
这种操作问题最佳的做法就要通过Connection接口提供的方法来处理。
NO. | 方法 | 类型 | 猫描述 |
01 | public void setAutoCommit(boolean autoCommit) throws SQLException | 普通 | 配置是否自动提交事务,如果设置为true表示自动提交,如果为false表示手动提交 |
02 | public void commit() throws SQLException | 普通 | 手工提交事务 |
03 | public void rollback() throws SQLException | 普通 | 回滚事务 |
如果要想进行合理的事务控制,那么就必须将自动提交的操作功能关闭,即“setAutoCommit(false)",当所有的更新操作全部配置完成之后则可以通过commitr)方法手工提交,如果提交更新的过程中出现了异常,那么就可以利用rollback()回滚当前事务。
范例:使用事务
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.Arrays;
public class JDBCDemo {
public static final String DRIVER = "com.mysql.cj.jdbc.Driver"; //数据库的驱动程序
public static final String URL="jdbc:mysql://localhost:3306/yootk"; //连接地址
public static final String USER = "root"; //用户名
public static final String PASSWORD = "mysqladmin"; //密码
public static void main(String[] args) throws Exception{
Class.forName(DRIVER);
Connection connection = DriverManager.getConnection(URL,USER,PASSWORD); //连接数据库
connection.setAutoCommit(false); //取消自动提交
Statement statement = connection.createStatement();
try{
//数据批量处理
statement.addBatch("INSERT INTO user (name) VALUES ('张三')");
statement.addBatch("INSERT INTO user (name) VALUES ('李四'')"); //故意让sql语句出错
statement.addBatch("INSERT INTO user (name) VALUES ('王五')");
statement.addBatch("INSERT INTO user (name) VALUES ('赵六')");
}catch (Exception e){
e.printStackTrace(); //输出异常
connection.rollback(); //回滚事务
}
int[] result = statement.executeBatch(); //执行并记录返回值
System.out.println("【批量处理结果】:"+ Arrays.toString(result));
connection.close(); //关闭连接
}
}
Exception in thread "main" java.sql.BatchUpdateException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''李四'')' at line 1
Caused by: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''李四'')' at line 1
此时的数据库没有数据产生:
不管后续你接触到了多少种开发框架,但是千万要记住,Java 中针对于事务控制的处理的核心操作全部都在Connection接口中有所定义,后续的事务控制仅仅是针对于这些功能进行了一些扩充而已。