当前位置: 首页 > news >正文

数据库事务以及JDBC实现事务

一、数据库事务

数据库事务(Database Transaction)是数据库管理系统中的一个核心概念,它代表一组操作的集合,这些操作要么全部执行成功,要么全部不执行,即操作数据的最小执行单元,保证数据库的数据一致性、完整性和可靠性。

一条数据库语句也是事务。

1、事务的ACID特性

1.原子性(Atomicity)

定义:事务中的操作要么全部完成,要么全部不做。

类比:就像你去银行进行转账操作,银行要么把钱从你账户转到对方账户,要么不做任何改变。如果途中出错,转账的整个过程会被“撤销”,就像根本没有进行过转账一样。

2.一致性(Consistency)

定义:事务开始之前和结束之后,数据库必须保持一致的状态。事务的执行不能破坏数据库的规则(如约束、触发器等)。

类比:银行的转账必须符合规则,比如账户的余额不能为负。即使你操作了很多次,只要操作成功,每次操作之后的账户余额都应该是合法的。

3.隔离性(Isolation)

定义:事务执行的过程中,其它事务不能看到中间的结果,直到事务完全提交。

类比:假设你和另一个人在银行同时转账,你的转账操作在完成前不会对对方的转账产生任何影响。如果没有隔离性,两个操作可能会影响对方的账户余额。

4.持久性(Durability)

定义:一旦事务提交,数据的修改是永久性的,即使系统崩溃,也不会丢失。

类比:转账一旦完成,银行系统保证这笔转账数据会被保留下来,哪怕系统发生故障,数据依然能够恢复。

2、事务的典型示例

假设你要从账户A转账100元到账户B,整个过程可能包括以下几个操作:

从账户A扣款100元

向账户B存款100元

如果这两个操作都成功完成,转账就完成了。但如果在第一个操作完成后,第二个操作失败了(比如系统崩溃),那么账户A的100元已经被扣除了,但是账户B并没有收到这100元。这种情况是不符合“原子性”的。

为了解决这个问题,数据库使用事务来确保:

原子性:要么两个操作都执行成功(100元从A扣除,B收到100元),要么两个操作都不执行(账户A和账户B保持原状)。

一致性:如果转账开始前的数据库状态是合法的(如余额不为负),那么转账完成后,数据库状态依然是合法的(A账户不会有负数,B账户的余额增加了100元)。

隔离性:在你完成转账前,别人无法看到你的转账结果,确保数据不会受到并发操作的影响。

持久性:一旦你提交了转账,无论系统发生什么故障,转账的数据都会保存下来。

3、MySQL客户端演示事务

1.准备数据集

建表:

CREATE TABLE t_account ( 
id INT PRIMARY KEY auto_increment, 
username VARCHAR ( 20 ), 
money DOUBLE 
);

插入测试数据:

INSERT INTO account
VALUES( 1, '美美', 10000 );
INSERT INTO account
VALUES( 2, '冠希', 10000 );
INSERT INTO account
VALUES( 3, '小凤', 10000 );
INSERT INTO account
VALUES( 4, '熊大', 10000 );
INSERT INTO account
VALUES( 5, '熊二', 10000 );

数据集准备完成。

2.实现事务的两种方式

(1)使用start transaction命令

熊大给小凤转账1000块

此时还未提交或者回滚,表明事务还没结束。如果此时发生异常,两个账户中的money会回到事务开启前的状态。

进行回滚

看到数据库是回到的事物开启前的状态。

此时进行了提交,看到数据库中数据已被改变

(2)设置MySQL事务默认不提交

MySQL数据库的事务是默认提交的

单独执行

 update account set money=money-1000 where username ="熊大";

MySQL将这视为一个事务,并默认提交

使用命令

set autocommit = off;

set autocommit = 0;

取消MySQL的默认提交事务

如果不手动提交事务或回滚事务,数据库中数据不做修改。

二、JDBC实现事务

JDBC实现事务只需要关闭MySQL的自动提交,并实现手动提交,即

// 关闭自动提交
conn.setAutoCommit(false);
// 手动提交事务
conn.commit();

当前数据库信息:

模拟转账Java操作数据库:

package com.goose;import com.goose.utils.JDBCUtils;import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;/*** @Author: Goose* @Description: TODO* @Date: 2025/5/11 11:19* @Version: 1.0*/public class JDBCShiWu {public static void main(String[] args) {Connection conn = JDBCUtils.getConnection();Statement stmt = null;try {// 关闭自动提交conn.setAutoCommit(false);stmt = conn.createStatement();String sql1 = "UPDATE account SET money = money - 1000 WHERE username = '熊大'";String sql2 = "UPDATE account SET money = money + 1000 WHERE username = '小凤'";int i = stmt.executeUpdate(sql1);// int a = 10/0;int i2 = stmt.executeUpdate(sql2);System.out.println("i = "+i+", i2 = "+ i2);// 手动提交事务// conn.commit();} catch (SQLException e) {e.printStackTrace();}finally{JDBCUtils.close(conn,stmt);}}
}

执行结果:

关闭自动提交后,不进行手动提交数据库信息不发生变化。

开启手动提交,数据库才能完成转账业务实现。

开启事务后,如果在执行SQL时发生异常,也不会提交事务

相关文章:

  • sql的性能分析
  • 嵌入式硬件篇---CAN
  • 嵌入式硬件篇---UART
  • 5java集合框架
  • 虚幻引擎5-Unreal Engine笔记之UE编辑器退出时的保存弹框
  • Level1.5算数运算符与赋值运算符
  • 时钟晶振锁相环pll方向技术要点和大厂题目解析
  • nvme Unable to change power state from D3cold to D0, device inaccessible
  • DS18B20温度传感器
  • [思维模式-25]:《本质思考力》-6- 马克思主义哲学的五对基本哲学范畴,以及在计算机领域的体现
  • Linux系统之----模拟实现shell
  • 技嘉主板BIOS升级
  • 单片机-STM32部分:10-2、逻辑分析仪
  • Android开发-Activity启停
  • JAVA练习题(2) 找素数
  • 【Bootstrap V4系列】学习入门教程之 组件-输入组(Input group)
  • (2025)图文解锁RAG从原理到代码实操,代码保证可运行
  • 【基于 LangChain 的异步天气查询2】GeoNames实现地区实时气温查询
  • 棒球裁判员学习指南·棒球1号位
  • dify插件接入fastmcp示例
  • 美国务卿鲁比奥将前往土耳其参加俄乌会谈
  • 法治课|争议中的“行人安全距离”于法无据,考量“注意义务”才更合理
  • 事关心脏健康安全,经导管植入式人工心脏瓣膜国家标准发布
  • 泽连斯基批准美乌矿产协议
  • 科普|“小”耳洞也会引发“大”疙瘩,如何治疗和预防?
  • 湖南湘西州副州长刘冬生主动交代问题,接受审查调查