程序员的知识教程库

网站首页 > 教程分享 正文

《JDBC》第12节:JDBC之事务的使用

henian88 2024-10-14 10:03:45 教程分享 7 ℃ 0 评论

前面已经介绍了JDBC之批量新增、批量删除、批量更新等操作,其中提到了事务的概念,这一小节就介绍一下JDBC中的事务处理功能。

1.1、什么是事务

事务是数据库中的一个概念,它是将多个要执行的SQL语句,当做一个整体来看待,当执行这些SQL语句的时候,要么全部执行成功,要么全部执行失败。也就是说,事务里面的每一个SQL语句,都必须执行成功,这一整个SQL语句才算执行成功,如果其中有一个执行失败,那么就不再继续执行后面的SQL语句,直接中止事务的执行。

事务有四个特性,分别是:Atomicity原子性、Consistency一致性、Isolation隔离性、Durability持久性,简称:ACID。

  • 原子性(Atomicity):指事务是一个不可分割的工作单位,要么全部执行,要么全部不执行。如果事务中的任何一部分操作失败,整个操作将被回滚,数据库状态将会回到事务开始之前的状态。
  • 一致性(Consistency):指在事务执行前后,数据库的完整性约束没有被破坏。换句话说,事务的执行不能使得数据库从一个一致性状态转变为另一个不一致的状态。举个例子:A给B转账100块,在事务执行成功之后,A账号会减少100块,B账号会增加100块,转账成功之后,A、B两个用户的账号都是正常的,账号里的钱是正确的,这就是一致性状态
  • 隔离性(Isolation):指多个事务同时执行时,每个事务的操作都应该与其他事务相互隔离,即使它们在同一时间内并发执行。这可以避免多个事务之间相互影响,减少并发引起的问题。
  • 持久性(Durability):指一旦事务完成提交,其所做的修改将永久保存在数据库中,即使系统发生故障,也不会丢失。

1.2、创建测试表

为了模拟事务,这里创建一张用户余额表t_user_balance,SQL语句如下所示:

CREATE TABLE `t_user_balance` (
  `id` varchar(255) NOT NULL COMMENT '主键ID',
  `balance` decimal(10,0) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- A用户
INSERT INTO `jdbc-study`.`t_user_balance`(`id`, `balance`) VALUES ('1001', 1000);
-- B用户
INSERT INTO `jdbc-study`.`t_user_balance`(`id`, `balance`) VALUES ('1002', 500);

1.3、setAutoCommit()方法

setAutoCommit()方法的作用:设置事务是否自动提交,对于MySQL数据库来说,它是默认自动提交事务的,所以我们如果要自己控制事务,那就需要将其设置成false。

// 取消事务的自动提交
connection.setAutoCommit(false);

1.4、commit()方法

commit()方法的作用:当事务执行成功之后,就可以调用commit()方法,将当前事务提交到数据库。

手动提交事务
connection.commit();

1.5、rollback()方法

rollback()方法的作用:当事务执行过程中,出现了异常情况,可以调用rollback()方法,将之前已经执行的代码回退。

// 手动回滚事务
connection.rollback();

1.6、完整案例代码

下面代码是A用户给B用户转账500元的场景,其中模拟了事务执行过程中,出现报错的情况。

package com.gitcode.jdbc.chapter12;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * @author ZhuYouBin
 * @version 1.0.0
 * @date 2024/6/26 13:50
 * @description 事务
 */
public class TransactionDemo {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        // 1、加载类对象,并且注册Driver驱动对象
        Class.forName("com.mysql.cj.jdbc.Driver");
        // 2、获取数据库连接
        String url = "jdbc:mysql://127.0.0.1:3306/jdbc-study";
        String username = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url, username, password);
        // 3、取消事务的自动提交
        connection.setAutoCommit(false);
        // 4、sql语句
        String sql = "update t_user_balance set balance = balance + ? where id = ?";
        PreparedStatement ps = connection.prepareStatement(sql);
        try {
            // 更新 A 用户金额
            ps.setBigDecimal(1, new BigDecimal("-500"));
            ps.setLong(2, 1001);
            // 执行代码
            ps.executeUpdate();

            // TODO 模拟执行过程中,报错的情况
            int i = 10 / 0;

            // 更新 B 用户金额
            ps.setBigDecimal(1, new BigDecimal("500"));
            ps.setLong(2, 1002);
            // 执行代码
            ps.executeUpdate();

            // 4.2、手动提交事务
            connection.commit();
            System.out.println("事务执行成功,已经提交!");
        } catch (Exception e) {
            // 4.3、手动回滚事务
            connection.rollback();
            System.out.println("事务执行失败,已经回滚!");
        }
        ps.close();
        // 关闭连接
        connection.close();
    }
}

执行结果,如下图所示:

1.7、源代码获取

源代码地址:

https://gitcode.com/qq_39826207/jdbc-study/tree/chapter-jdbc-12

今天就到这里,未完待续~~

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表