JDBC 中数据库事务实现

目标

1,使用jdbc代码,添加数据库事务动作!

2,开启事务

3,事务提交 / 事务回滚

事务概念回顾

// 事务概念
   数据库事务就是一种SQL语句执行的缓存机制,不会单条执行完毕就更新数据库数据,最终根据缓
   存内的多条语句执行结果统一判定!
   一个事务内所有语句都成功及事务成功,我们可以触发commit提交事务来结束事务,更新数据!
   一个事务内任意一条语句失败,及事务失败,我们可以触发rollback回滚结束事务,
   数据回到事务之前状态!
   
   举个例子: 
           临近高考,你好吃懒做,偶尔还瞎花钱,父母也只会说'你等着!',待到高考完毕!
           成绩600+,翻篇,庆祝!
           成绩200+,翻旧账,男女混合双打!
           
//优势
   允许我们在失败情况下,数据回归到业务之前的状态! 
   
//场景
   一个业务涉及多条修改数据库语句!
   例如: 经典的转账案例,转账业务(加钱和减钱)   
         批量删除(涉及多个删除)
         批量添加(涉及多个插入)     
         
// 事务特性
  1. 原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。 

  2. 一致性(Consistency)事务必须使数据库从一个一致性状态变换到另外一个一致性状态。

  3. 隔离性(Isolation)事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

  4. 持久性(Durability)持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响

// 事务类型
  
  自动提交 : 每条语句自动存储一个事务中,执行成功自动提交,执行失败自动回滚! (MySQL)
  手动提交:  手动开启事务,添加语句,手动提交或者手动回滚即可!
  
// sql开启事务方式
   针对自动提交: 关闭自动提交即可,多条语句添加以后,最终手动提交或者回滚! (推荐)
     
      SET autocommit = off; //关闭当前连接自动事务提交方式
      # 只有当前连接有效
      # 编写SQL语句即可
      SQL
      SQL
      SQL
      #手动提交或者回滚 【结束当前的事务】
      COMMIT / ROLLBACK ;  
     
   手动开启事务: 开启事务代码,添加SQL语句,事务提交或者事务回滚! (不推荐)

// 呼应jdbc技术
 
  try{
    connection.setAutoCommit(false); //关闭自动提交了
    
    //注意,只要当前connection对象,进行数据库操作,都不会自动提交事务
    //数据库动作!
    //statement - 单一的数据库动作 c u r d 
    
    connection.commit();
  }catch(Execption e){
    connection.rollback();
  }

数据库表数据

-- 继续在huan的库中创建银行表
CREATE TABLE t_bank(
   id INT PRIMARY KEY AUTO_INCREMENT COMMENT '账号主键',
   account VARCHAR(20) NOT NULL UNIQUE COMMENT '账号',
   money  INT UNSIGNED COMMENT '金额,不能为负值') ;
   
INSERT INTO t_bank(account,money) VALUES
  ('ergouzi',1000),('lvdandan',1000);

代码结构设计

在这里插入图片描述

JDBC事务实现

BankDao层类

package com.jdbc.transaction;

import java.sql.*;

/**
 * @author : Aurora
 * @Date : 2023/1/4
 * @Describe : bank表的数据库操作方法存储类
 */
public class BankDao {

    /**
     * 加钱的数据库操作方法(JDBC)
     *
     * @param account 加钱的行号
     * @param money   加钱的金额
     */
    public void add(String account, int money,Connection conn) throws ClassNotFoundException, SQLException {

        //编写SQL语句结果
        String sql = "update t_bank set money = money + ? where account = ?;";

        //创建statement
        PreparedStatement preparedStatement = conn.prepareStatement(sql);

        //占位符
        preparedStatement.setObject(1, money);
        preparedStatement.setString(2, account);

        //发送sql语句
        preparedStatement.executeUpdate();

        //关闭资源
        preparedStatement.close();

        System.out.println("加钱成功!");
    }

    /**
     * 减钱的数据库操作方法(JDBC)
     *
     * @param account 减钱的行号
     * @param money   减钱的金额
     */
    public void sub(String account, int money,Connection conn) throws SQLException, ClassNotFoundException {

        //编写SQL语句结果
        String sql = "update t_bank set money = money - ? where account = ?;";

        //创建statement
        PreparedStatement preparedStatement = conn.prepareStatement(sql);

        //占位符
        preparedStatement.setObject(1, money);
        preparedStatement.setString(2, account);

        //发送sql语句
        preparedStatement.executeUpdate();

        //关闭资源
        preparedStatement.close();

        System.out.println("减钱成功!");
    }

}

BankService类

package com.jdbc.transaction;

import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * @author : Aurora
 * @Date : 2023/1/4
 * @Describe : 银行卡业务方法,调用dao方法
 */
public class BankService {

    /**
     * TODO: 事务添加在业务方法中!
     * 利用try catch代码块,开启事务和提交事务,以及事务回滚!
     * 将connection传入dao层即可,dao只负责使用,不要close();
     *
     * @param addAccount
     * @param subAccount
     * @param money
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    public void transfer(String addAccount, String subAccount, int money) throws SQLException, ClassNotFoundException {

        BankDao bankDao = new BankDao();

        //一个事务的最基本要求,必须是同一个连接对象 connection

        //[一个转账方法,属于同一个事务 (加钱,减钱)]

        //注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

        //获取连接
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:13306/huan", "root", "123456");

        try {
            //开启事务
            //关闭事务提交
            conn.setAutoCommit(false);

            //执行数据库动作
            bankDao.add(addAccount, money, conn);

            System.out.println("--------------------");

            bankDao.sub(subAccount, money, conn);

            //事务提交
            conn.commit();

        } catch (Exception e) {

            //事务回滚
            conn.rollback();

            //抛出异常
            throw e;
        } finally {
            conn.close();
        }
    }

    @Test
    public void start() throws SQLException, ClassNotFoundException {
        //二狗子给驴蛋蛋转500
        transfer("lvdandan", "ergouzi", 500);
    }
}

测试类

package com.jdbc.transaction;

import java.sql.SQLException;

/**
 * @author : Aurora
 * @Date : 2023/1/4
 * @Describe : 启动类
 */
public class Test {
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        //二狗子给驴蛋蛋转500
        BankService bankService = new BankService();
        bankService.transfer("lvdandan", "ergouzi", 500);
    }
}

按着案例敲,深入思考

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JDBCJava数据库连接的缩写,它是一组用于操作数据库Java API。JDBC提供了一种标准的方式来连接和操作各种关系型数据库,包括Oracle、MySQL、SQL Server等。 JDBC可以通过调用存储过程来执行数据库操作,存储过程是一组预先编译好的SQL语句,可以在需要的时候被调用。在JDBC,可以通过以下步骤来调用存储过程: 1. 创建CallableStatement对象,该对象用于调用存储过程。 2. 设置存储过程的参数,包括输入参数、输出参数和返回值。 3. 执行存储过程,并获取输出参数和返回值。 下面是一个调用存储过程的示例代码: ``` String sql = "{call my_proc(?, ?, ?)}"; CallableStatement stmt = conn.prepareCall(sql); stmt.setInt(1, 100); stmt.setString(2, "John"); stmt.registerOutParameter(3, Types.INTEGER); stmt.execute(); int result = stmt.getInt(3); ``` 除了调用存储过程,JDBC还可以处理数据库事务事务是一组相关的数据库操作,要么全部执行成功,要么全部回滚到之前的状态。在JDBC,可以通过以下步骤来处理数据库事务: 1. 关闭自动提交模式,这样每个SQL语句就不会自动提交到数据库。 2. 开始事务,即调用Connection对象的beginTransction()方法。 3. 执行一组SQL语句。 4. 如果所有的SQL语句都执行成功,就调用Connection对象的commit()方法提交事务。 5. 如果任何一个SQL语句执行失败,就调用Connection对象的rollback()方法回滚事务。 下面是一个处理数据库事务的示例代码: ``` try { conn.setAutoCommit(false); stmt1.executeUpdate(); stmt2.executeUpdate(); conn.commit(); } catch (SQLException e) { conn.rollback(); } finally { conn.setAutoCommit(true); } ``` 在这个示例,stmt1和stmt2是两个SQL语句,如果它们都执行成功,就提交事务。如果任何一个SQL语句执行失败,就回滚事务。最后,要记得将自动提交模式重新设置为true。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值