数据库事务:ACID特性与实战应用

一,初步认识事务

事务是把一组sql语句打包为一个整体,在这组sql的执行过程中,要么全部成功,要么全部失败

举个栗子:我的账户有500元,小帅账户有 200 元,我要转200元给小帅

转账必须做 2 步:1 从我的账户扣200 → 剩300.

2小帅账户加 200 → 剩 400

但如果产生:扣了我的钱,还没给小帅加钱,突然断电!这就是没有事务的后果(灾难)我平白无故少了200,小帅也未收到

有事务时(安全):事务会自动撤销所有操作,回到转账开始前的状态:我还是500,小帅也有200。钱一分没少,操作等于没发生

二,事务的ACID特性

2.1 Atomicity(原子性)

支持事务的数据库中最基本的一个特性,一组sql要么全都执行成功,要么全都不执行,不会出现只执行一半的情况,如果说事务执行过程中出现错误,事务就会回滚到事务开始的状态,就像这个事务没有执行过一样

2.2 Consistency(一致性)

事务执行完成后,保证数据正确并且符合预期

2.3 Isolation(隔离性)

多个事务之间不能相互影响

2.4 Durabbility(持久性)

事务一旦提交,就需要保存在存储介质中,不论数据库是否损坏,都不会影响数据的安全(不能丢失)

事务最终要保证一致性,一致性是由原子性,隔离性和持久性来实现的

三,使用事务

3.1 查看支持事物的存储引擎

要使用事务那么数据库就要支持事务,在MySQL中支持事务的存储引擎是InnoDB,可以通过
show engines; 语句查看

3.2 控制事务语法

复制代码
# 开始⼀个新的事务
START TRANSACTION;
# 或
BEGIN;

# 提交当前事务,并对更改持久化保存
COMMIT;

# 回滚当前事务,取消其更改
ROLLBACK;

无论提交或是回滚,事务都会关闭

举个栗子:

提交时:commit后数据持久化到硬盘

回滚时:rollback后回到事务开始时

3.3 保存点

在事务执行的过程中设置保存点,回滚时指定保存点可以把数据恢复到保存点的状态

1.在要保存的内容后设置:savepoint savepoint1;

2.以 rollback to savepoint1; 回滚到指定地方

3.4 自动/手动提交事务

默认情况下,mysql是自动提交事务,在发生异常时自动回滚,可用show variables like 'autocommit';来查看当前事务是否提交

通过以下语句设置事务为手动提交或自动提交

设置事务自动提交

mysql> SET AUTOCOMMIT=1;
mysql> SET AUTOCOMMIT=ON;

设置事务手动提交

mysql> SET AUTOCOMMIT=0;
mysql> SET AUTOCOMMIT=OFF;

注:只要使⽤ START TRANSACTION 或 BEGIN 开启事务,必须要通过 COMMIT 提交才会持久 化,与是否设置 SET autocommit 无关。 手动提交模式下,不用显示开启事务,执行修改操作后,提交或回滚事务时直接使用commit 或 rollback 。已提交的事务不能回滚

四,事务的隔离性和隔离级别

4.1 什么是隔离性

事务的隔离性:mysql可同时被多个客户访问,为了保证不同客户端在对同条数据修改时出现的互相影响的情况,事务之间就需要互相隔离,也就是隔离性

4.2 隔离级别

在mysql的InnoDB引擎中有四种隔离级别:

read uncommitted 读未提交

read committed 读已提交

repeatable read 可重复读(默认)

serializable 串行化

4.3 查看和设置隔离级别

4.3.1 查看

事务的隔离级别分为全局作用域和会话作用域,查看不同作用域事务的隔离级别有不同的方式

全局作⽤域

SELECT @@GLOBAL.transaction_isolation;

会话作⽤域

SELECT @@SESSION.transaction_isolation;

4.3.2 设置

设置事务的隔离级别和访问模式

通过GLOBAL|SESSION分别指定不同作用域的事务隔离级别

SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL level|access_mode;

隔离级别

level: {
REPEATABLE READ # 可重复读
READ COMMITTED # 读已提交
READ UNCOMMITTED # 读未提交
SERIALIZABLE # 串行化

访问模式

access_mode: {
READ WRITE # 表示事务可以对数据进行读写
READ ONLY # 表示事务是只读,不能对数据进行读写

4.4 read uncommitted 读未提交与脏读

由于在读取数据时不做任何限制,所以并发性能很高,容易出现数据安全问题,如:在事务1执行了update语句,但未执行commit时,会在事务2中被读取到,如果事务1在此时回滚,那么事务2刚才读的数据没有任何意义,这个现象叫做脏读。在业务中发生这种问题通常会有很严重的后果,所以应避免使用read committed读未提交这种的隔离级别

4.5 read committed 读已提交和不可重复读

为解决脏读,把事务隔离等级设为read commited,这时可能会产生不可重复读现象,如事务1先对某条事务进行查询,之后事务2对此事务进行修改,事务1在读此事务时,得到事务2修改后的结果,导致事务1前后两次读取不一样,这个现象叫不可重复读

4.6 repeatable read 可重复读与幻读

为解决不可重复读问题,可把事务隔离等级设为repeatable read,这时同一事务任何时候读取数据都是相同的,但是会出现新的问题,如事务1查询了一个区间的记录得到结果集1,事务2向这个区间的间隙中写入了一条记录并提交,事务1在查询这个区间的结果集时会查到事务2写的结果集2,两次结果集不一样,这就是**幻读。**但mysql中的InnoDB存储引擎用了next-key锁解决了大部分幻读问题

4.7 serializable 串行化

进一步提高事务的隔离级别,此时所有事务串行执行,可以解决所有并发中的安全问题

4.8 不同隔离级别的区别

五,JDBC

我们前面提到的都是用mysql来操作数据库,接下来来介绍用程序操作数据库

JDBC是java程序和数据库间的桥梁,包含了一套java定义的用于执行sql语句的接口,使开发者可以编写数据库的程序。

JDBC的主要作用:与数据库建立连接,发送sql语句和处理数据执行结果

JDBC的使用

JDBC使用过程可以概括为:加载数据库厂商的驱动包,建立连接,创建Statement,执行sql,处理结果释放资源和关闭链接

六,小结

这节概念性比较强,大家可以细细研究。如果方便的话请给我点点赞,谢谢啦

相关推荐
晚风_END18 分钟前
Linux|操作系统|zfs文件系统的使用详解
linux·运维·服务器·数据库·postgresql·性能优化·宽度优先
AI进化营-智能译站2 小时前
ROS2 C++开发系列17-多线程驱动多传感器|chrono高精度计时实现机器人同步控制
java·c++·ai·机器人
天若有情6735 小时前
程序员原创|借鉴JS事件冒泡,根治电脑文件混乱的“冒泡整理法”
开发语言·javascript·windows·ecmascript·电脑·办公·日常
qq_589568106 小时前
springbootweb案例,出现访问 http://localhost:8080/list 一直处于浏览器运转阶段
java·网络协议·http·list·springboot
JAVA面经实录9176 小时前
计算机基础(完整版·超详细可背诵)
java·linux·数据结构·算法
晚风_END6 小时前
Linux|操作系统|最新版openzfs编译记录
linux·运维·服务器·数据库·spring·中间件·个人开发
特种加菲猫6 小时前
继承,一场跨越时空的对话
开发语言·c++
AC赳赳老秦6 小时前
知识产权辅助:用 OpenClaw 批量生成专利交底书 / 软著申请材料,自动校验格式与内容合规性
java·人工智能·python·算法·elasticsearch·deepseek·openclaw
dLYG DUMS7 小时前
DBeaver连接本地MySQL、创建数据库表的基础操作
数据库·mysql