mysql--事务

目录

1、什么是事务?

2、事务的特点

3、事务相关操作

(1)查看事务

[(2) 关掉 / 打开自动提交](#(2) 关掉 / 打开自动提交)

(3)启用事务

(4)记录节点

(5)回滚

(6)提交事务

4、事务异常

5、事务隔离性

(1)隔离级别

(2)查看隔离级别

(3)设置隔离级别

(4)隔离级别:读未提交

(5)隔离级别:读提交

(6)隔离级别:可重复读

(7)隔离级别:串行化

6、事务的一致性理解


1、什么是事务?

事务这个概念的提出,是为了解决一个问题。

什么问题?

数据库是一个给上层用户提供疏通处理服务的实体

由此,不可避免的,会有多个用户同时对数据库有需求,即同时访问

同时访问,就会有并发的情况

同时访问,就会产生冲突和相关问题

举一个例子:

火车票购票系统

会出现很多人同时买票的场景

现在假设,数据表示A车厢,只有一张票

但是,现在有100个人在同时买这个车厢的票

现在,甲买了票,显示成功

按理说,剩余的其他人,将无法买到这张票

但是,票数-1的操作,数据库没有及时更新

于是,现在问题来了:

剩余的人,都发现仍然有一张票存在

既然有票,那就买

于是,明明只有一张票,却卖出了100份!

这事情就大了

事实上,由于数据库CURD对数据库和数据表的属性性质

其本身仅仅是操作和修改,并不能保证数据的安全访问和原子性的问题

所以,有问题!需要解决。

如何解决?

事务来解决。

那么,什么是事务?

事务就是一组DML语句组成的整体,要么成功,要么失败。

理解事务要从用户的需求去看

而不是站在程序员的技术角度

例如,转账100的数据库实现,

肯定是A的账户+100,B的账户-100

数据库的语句,应当是两句话,而不是一句话

但是,对于用户来说,转账的实现,应该是一个整体

用户不关心那个+100,那个-100

所以,对于用户来说,转账,就是一个事务

一个天然就应该是整体的事情

这,就是事务

所以,现在回到程序员的视角来看

事务,就是完成用户一个事情整体逻辑的多个语句的封装。

为什么会出现事务?

本质是为了当应用程序访问数据库时,

事务能够简化我们的编程模型

让程序员 / 上层不用去考虑各种并发问题和错误

所以,事务不是天生就有的

而是为了更好让上层使用数据库

让上层程序员不用关心底层细节

2、事务的特点

原子性 (Atomicity)

定义: 原子性确保事务中的所有操作要么全部成功,要么全部失败。如果事务中的任何一个操作失败,系统会回滚(rollback)到事务开始前的状态,确保数据库不会进入一个不一致的状态。

理解: 可以将原子性理解为"要么全部完成,要么全不做"。例如,在转账操作中,如果从一个账户扣款成功,但向另一个账户存款失败,则整个转账事务将回滚,确保两个账户的状态不变。

  1. 一致性 (Consistency)

定义: 一致性确保在事务开始前和结束后,数据库的完整性约束保持不变。在执行事务时,数据的状态必须从一个一致性状态转变为另一个一致性状态。

理解: 例如,如果数据库有一个约束,确保账户余额不能为负数,那么在事务结束后,所有账户余额依然不能为负数。事务的执行不能破坏这种一致性。

  1. 隔离性 (Isolation)

定义: 隔离性确保并发执行的事务之间不会互相干扰。事务的执行结果在被提交之前对其他事务是不可见的。

理解: 例如,两个事务同时操作同一数据时,隔离性确保一个事务的操作不会被另一个事务看到,直到第一个事务提交完成。这是通过使用锁机制和隔离级别来实现的。MySQL支持多种隔离级别,包括:

读未提交 (Read Uncommitted): 事务可以读取其他未提交事务的数据。

读已提交 (Read Committed): 事务只能读取已提交的数据。

可重复读 (Repeatable Read): 在事务开始后,任何对数据的读取都将返回相同的数据,直到事务结束。

串行化 (Serializable): 最严格的隔离级别,强制事务串行执行,完全隔离。

  1. 持久性 (Durability)

定义: 持久性确保一旦事务提交,其结果是永久性的,即使系统发生崩溃或故障,已提交的数据也不会丢失。

理解: 例如,完成的交易记录将保存在数据库中,无法通过系统重启或崩溃而丢失。MySQL通过日志记录和数据备份机制来实现持久性。

3、事务相关操作

一定要将抽象具体化,具体化就可以被想象

(1)查看事务

cpp 复制代码
show variables like 'autocommit';

(2) 关掉 / 打开自动提交

cpp 复制代码
set autocommit = 0 / 1;

(3)启用事务

cpp 复制代码
start transaction;
#从该语句开始以后的所有语句都属于同一个事务
cpp 复制代码
begin;#启用事务

(4)记录节点

cpp 复制代码
savepoint point1;
#每一次执行语句结束后,使用该语句,标记节点

(5)回滚

cpp 复制代码
rollbacrk to point1;
#取消节点对应语句
#如果没有设置保存点,默认回滚到开始
cpp 复制代码
rollback;
#取消所有事务操作

(6)提交事务

cpp 复制代码
commit;
#事务一旦提交,无法回滚

4、事务异常

如果事务中间中断,遇到异常,没有完成,系统会自动回滚,即撤回所有操作。

但只要commit提交以后,数据就插入成功

我们原来写的所有的单mysql语句全部都是事务,只是开启了自动提交

对于innodb来说,每一句语句都会被封装成事务,自动提交

如果自动提交打开了,那该语句会被自动提交

如果没有打开,此时如果系统崩溃,回滚,语句操作被撤销

5、事务隔离性

(1)隔离级别

什么叫做隔离?

mysql是一个服务端,不可避免的要被许多客户端同时访问

那么当有一个事务在执行时,就要进行隔离,避免打扰冲突

因此要给正在执行的事务增加一个隔离,

同时根据事务的重要程度,区分隔离等级,即可以被干扰的程度

在事务处理中,隔离是必要的

运行中的事务,进行互相隔离

各自互不干扰,即隔离性

根据影响程度的不同,分配隔离级

四种隔离级别:

特点 描述
原子性 事务被视为一个整体,要么全部完成,要么全部不做。即使在事务执行过程中发生错误,事务中的所有操作也会被撤回。
一致性 事务的执行将数据库从一个一致性状态转变为另一个一致性状态。确保在事务完成后,所有数据都满足定义的规则和约束。
隔离性 并发执行的事务彼此之间是隔离的,一个事务的执行不应受到其他事务的干扰。隔离级别可以调节事务的可见性。
持久性 一旦事务被提交,对数据库的修改将是永久的,即使系统崩溃,数据也不会丢失。

(2)查看隔离级别

cpp 复制代码
select @@global.tx.isolaton;

(3)设置隔离级别

cpp 复制代码
set session transation isolation level read commited;

(4)隔离级别:读未提交

A事务的语句,例如修改、插入、更新等执行

还没有提交,其他事务就可以看到A事务对应执行改变的表

就是,我A事务还没有结束,没有commit,其他事务就可以查看了

因此,也成为脏读

这种个理解级别很低,不推荐

(5)隔离级别:读提交

当前事务在执行的操作,其他事务不能看到

只有commit,提交之后,其他事务才能看到

这种隔离级别有一个问题,即不可重复读取

不可重复读:

事务在多次读取时查看到的数据可能不一样

因为在并发时间内,可能有其他事务对数据进行了修改操作

但是,这是不应该的,因为事务的一切操作应当是原子性的

因此,这种隔离级别也不是很高,不是很推荐

(6)隔离级别:可重复读

可重复读:和不可重复读相反

两个事务并发运行时,即使一个事务提交,也不影响另一个事务

即,一个事务在多次查看读取数据时,数据不会发生变动

隔离事实上是对数据进行枷锁完成的

(7)隔离级别:串行化

对所有的事务进行枷锁,串行化进行,就是同一个时间只能有一个事务运行

很安全,但是效率极低

6、事务的一致性理解

相关推荐
IT项目管理28 分钟前
达梦数据库DMHS介绍及安装部署
linux·数据库
你都会上树?35 分钟前
MySQL MVCC 详解
数据库·mysql
大春儿的试验田40 分钟前
高并发收藏功能设计:Redis异步同步与定时补偿机制详解
java·数据库·redis·学习·缓存
Ein hübscher Kerl.1 小时前
虚拟机上安装 MariaDB 及依赖包
数据库·mariadb
长征coder1 小时前
AWS MySQL 读写分离配置指南
mysql·云计算·aws
醇醛酸醚酮酯2 小时前
Qt项目锻炼——TODO清单(二)
开发语言·数据库·qt
ladymorgana2 小时前
【docker】修改 MySQL 密码后 Navicat 仍能用原密码连接
mysql·adb·docker
PanZonghui2 小时前
Centos项目部署之安装数据库MySQL8
linux·后端·mysql
GreatSQL社区2 小时前
用systemd管理GreatSQL服务详解
数据库·mysql·greatsql
掘根2 小时前
【MySQL进阶】错误日志,二进制日志,mysql系统库
数据库·mysql