day47-JDBC和连接池03

JDBC和连接池038.事务8.1事务介绍

  • 基本介绍
  1. JDBC程序中当一个Connection对象创建时,默认情况下是自动提交事务:每次执行一个SQL语句时,如果执行成功,就会向数据库自动提交,而不能回滚 。
  2. JDBC程序中为了让多个SQL语句作为一个整体执行,需要使用事务
  3. 调用Connection的setAutoCommit(false)可以取消自动提交事务
  4. 在所有的SQL语句都执行成功后,调用Connection的commit();方法提交事务
  5. 在其中某个操作失败或者出现异常时 , 调用Connection的rollback();方法回滚事务
【day47-JDBC和连接池03】
day47-JDBC和连接池03

文章插图

day47-JDBC和连接池03

文章插图
8.2事务处理
应用实例
模拟经典的转账业务
首先创建一张account表,插入两条数据
CREATE TABLE ACCOUNT( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(32) NOT NULL DEFAULT '', balance DOUBLE NOT NULL DEFAULT 0)CHARACTER SET utf8;INSERT INTO ACCOUNT VALUES(NULL,'马云',3000),(NULL,'马化腾',10000);SELECT * FROM ACCOUNT;
day47-JDBC和连接池03

文章插图
package li.jdbc.transaction_;import li.jdbc.utils.JDBCUtils;import org.junit.Test;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;/** * 演示JDBC中如何使用事务 */public class Transaction_ {//没有使用事务@Testpublic void noTransaction() {//操作转账业务//1.得到连接Connection connection = null;//2.组织sql语句String sql = "update account set balance=baLance-100 where id=1";String sql2 = "update account set balance=baLance+100 where id=2";//3.创建PreparedStatement对象PreparedStatement preparedStatement = null;try {connection = JDBCUtils.getConnection();//在默认情况下 , connection默认自动提交preparedStatement = connection.prepareStatement(sql);preparedStatement.executeUpdate(); //执行第一条sqlint i = 1 / 0;//抛出异常--模拟异常可能--可以看到出现异常状态之后的语句没有执行preparedStatement = connection.prepareStatement(sql2);preparedStatement.executeUpdate();//执行第二条sql} catch (SQLException e) {e.printStackTrace();} finally {//关闭资源JDBCUtils.close(null, preparedStatement, connection);}}//使用事务来解决@Testpublic void useTransaction() {//操作转账业务//1.得到连接Connection connection = null;//2.组织sql语句String sql = "update account set balance=baLance-100 where id=1";String sql2 = "update account set balance=baLance+100 where id=2";//3.创建PreparedStatement对象PreparedStatement preparedStatement = null;try {connection = JDBCUtils.getConnection();//在默认情况下,connection默认自动提交//将connection设置为不自动提交connection.setAutoCommit(false);preparedStatement = connection.prepareStatement(sql);preparedStatement.executeUpdate(); //执行第一条sqlint i = 1 / 0;//抛出异常preparedStatement = connection.prepareStatement(sql2);preparedStatement.executeUpdate();//执行第二条sql//在这里提交事务connection.commit();} catch (Exception e) {//如果在try里面出现了异常,就会进入catch语句 , // 这意味着我们可以在catch语句里面进行回滚,即撤销执行的SQL语句System.out.println("执行发生了异常 , 撤销已执行的SQL");try {connection.rollback();//没有填写保存点就默认回滚到事务开始的状态} catch (SQLException ex) {ex.printStackTrace();}e.printStackTrace();} finally {//关闭资源JDBCUtils.close(null, preparedStatement, connection);}}}
  1. 没有使用事务(noTransaction)的运行结果:可以看到因为默认为直接提交事务,在出现异常后没有执行异常后面的语句就进入了catch语句,造成数据错误

day47-JDBC和连接池03

文章插图
day47-JDBC和连接池03

文章插图
  1. 使用了事务(useTransaction)之后:可以看到由于在catch语句中进行了回滚操作,在捕获到异常之后直接进行回滚,保证数据的一致性

day47-JDBC和连接池03

文章插图
day47-JDBC和连接池03

文章插图
9.批处理
  • 基本介绍
  1. 当需要成批插入或者更新记录时,可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理 。通常情况下比单独提交处理更有效率
  2. JDBC的批量处理语句包括下面方法: