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

数据库事务以及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时发生异常,也不会提交事务

http://www.xdnf.cn/news/5398.html

相关文章:

  • 模型欠拟合是什么?
  • 基于VSCode + PlatformIO平台的ESP8266的DS1302实时时钟
  • AI日报 · 2025年05月11日|传闻 OpenAI 考虑推出 ChatGPT “永久”订阅模式
  • Linux中常见开发工具简单介绍
  • 05.three官方示例+编辑器+AI快速学习three.js webgl - animation - skinning - ik
  • Three.js + React 实战系列 - 职业经历区实现解析 Experience 组件✨(互动动作 + 3D 角色 + 点击切换动画)
  • MySql(进阶)
  • 【大模型】AI智能体Coze 知识库从使用到实战详解
  • 基于Dify实现对Excel的数据分析
  • 嵌入式硬件篇---陀螺仪|PID
  • Linux之进程概念
  • 电源架构与太阳能充电器电路设计分析
  • OpenWrt开发第8篇:树莓派开发板做无线接入点
  • langchain 接入国内搜索api——百度AI搜索
  • Qt 样式表:全面解析与应用指南
  • LeetCode 高频题实战:如何优雅地序列化和反序列化字符串数组?
  • 理解 Token 索引 vs 字符位置
  • C++23 新特性:深入解析 std::views::join_with(P2441R2)
  • 深入解析 Vision Transformer (ViT) 与其在计算机视觉中的应用
  • 效率办公新工具:PDF Reader Pro V5.0功能解析与使用体验
  • NHANES稀有指标推荐:MedHi
  • M. Moving Both Hands(反向图+Dijkstra)
  • 视频编解码学习10之成像技术原理
  • 华为配置篇-RSTP/MSTP实验
  • 股指期货的保证金交易和资金门槛是多少?
  • 《Go小技巧易错点100例》第三十三篇
  • Redis--常见数据类型List列表
  • 思维链框架:LLMChain,OpenAI,PromptTemplate
  • 游戏引擎学习第274天:基于弹簧的动态动画
  • 【MySQL】表空间结构 - 从何为表空间到段页详解