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

文章插图
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语句 , 造成数据错误

    经验总结扩展阅读