JDBC p3 事务

打印 上一主题 下一主题

主题 992|帖子 992|积分 2976

事务


  • 基本介绍

    • JDBC 程序中当一个Connection对象创建时,默认情况下是自动提交事务:每次执行一个 SQL 语句时,如果执行成功,就会向数据库自动提交,而不能回滚。
    • JDBC程序中为了多个SQL语句作为一个整体执行,需要使用事务。
    • 调用 Connection 的 setAutoCommit(false) 可以取消自动提交事务(相当与开启了事务)。
    • 在所有的 SQL 语句都成功执行后,调用 commit(); 方法提交事务。
    • 在其中某个操作失败或出现异常时,调用 rollback(); 方法回滚事务。

  • 案例:模拟经典的转账的业务
    MySQL代码:
    1. CREATE TABLE account(
    2.         id INT PRIMARY KEY AUTO_INCREMENT,
    3.         name VARCHAR(32) NOT NULL DEFAULT '',
    4.         balance DOUBLE NOT NULL DEFAULT 0
    5. ) CHARACTER SET utf8;
    6. INSERT INTO account VALUES(NULL, '马云', 3000);
    7. INSERT INTO account VALUES(NULL, '马化腾', 10000);
    8. SELECT * FROM account;
    复制代码
    Java代码:
    1. package com.hspedu.jdbc.transaction_;
    2. import com.hspedu.jdbc.utils.JDBCUtils;
    3. import org.junit.jupiter.api.Test;
    4. import java.sql.Connection;
    5. import java.sql.PreparedStatement;
    6. import java.sql.SQLException;
    7. /**
    8. * Description: 演示在jdbc 中如何使用事务
    9. */
    10. public class Transaction_ {
    11.     //没有使用事务,模拟银行转账出现异常
    12.     @Test
    13.     public void noTransaction(){
    14.         //1. 得到连接
    15.         Connection connection = null; //默认情况下,connection 默认自动提交, 执行一句sql语句,就会提交事务
    16.         //2. SQL语句
    17.         String sql = "update account set balance = balance - 100 where id = ?";
    18.         String sql2 = "update account set balance = balance + 100 where id = ?";
    19.         PreparedStatement preparedStatement = null;
    20.         //3. 创建PreparedStatement 对象
    21.         try {
    22.             connection = JDBCUtils.getConnection();
    23.             preparedStatement = connection.prepareStatement(sql);
    24.             preparedStatement.setInt(1, 1);
    25.             preparedStatement.executeUpdate();
    26.              int i = 1 / 0; //抛出异常接下来的语句就不会执行
    27.             preparedStatement = connection.prepareStatement(sql2);
    28.             preparedStatement.setInt(1, 2);
    29.             preparedStatement.executeUpdate();
    30.         } catch (SQLException e) {
    31.             e.printStackTrace();
    32.         }finally {
    33.             //关闭资源
    34.             JDBCUtils.close(null, preparedStatement, connection);
    35.         }
    36.     }
    37.     //使用事务
    38.     @Test
    39.     public void UseTransaction() {
    40.         //1. 得到连接
    41.         Connection connection = null; //默认情况下,connection 默认自动提交, 执行一句sql语句,就会提交事务
    42.         //2. SQL语句
    43.         String sql = "update account set balance = balance - 100 where id = ?";
    44.         String sql2 = "update account set balance = balance + 100 where id = ?";
    45.         PreparedStatement preparedStatement = null;
    46.         //3. 创建PreparedStatement 对象
    47.         try {
    48.             connection = JDBCUtils.getConnection();
    49.             connection.setAutoCommit(false);//相当与开启了事务
    50.             preparedStatement = connection.prepareStatement(sql);
    51.             preparedStatement.setInt(1, 1);
    52.             preparedStatement.executeUpdate();
    53.             int i = 1 / 0; //抛出异常接下来的语句就不会执行
    54.             preparedStatement = connection.prepareStatement(sql2);
    55.             preparedStatement.setInt(1, 2);
    56.             preparedStatement.executeUpdate();
    57.             //这里提交事务
    58.             connection.commit();
    59.         } catch (SQLException  | ArithmeticException  e) {
    60.             System.out.println("执行发生了异常,撤销执行的SQL");
    61.             e.printStackTrace();
    62.             //可以在这里进行回顾,即撤销执行的sql语句
    63.             try {
    64.                 connection.rollback();//默认回滚到事务开始的时候,可以填入回滚点savePoint
    65.             } catch (SQLException ex) {
    66.                 throw new RuntimeException(ex);
    67.             }
    68.         } finally {
    69.             //关闭资源
    70.             JDBCUtils.close(null, preparedStatement, connection);
    71.         }
    72.     }
    73. }
    复制代码

    • 模拟1号向2号转账100元转账异常,调用noTransaction()方法,不使用事务,可以发现结果如下:

      发生异常后,1号的存款转出了 100元,2号没有收到100元,100元没了。
    • 如果调用的是useTransaction()方法,使用事务(connection.setAutoCommit(false) 取消事务自动提交)结果如下:

      没有变化,控制台打印了 “执行发生了异常,撤销执行的SQL”,出现了异常后try-catch并进行了事务的回滚


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

笑看天下无敌手

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表