MySQL 事务处理语言 TCL

news2024/11/24 12:23:36

文章目录

  • 事务处理语言 TCL
    • 事务简介
    • 事务控制
    • 并发事务的隔离挑战
      • 脏读
      • 不可重复读
      • 幻读
    • 事务的隔离级别
      • 未提交读(READ-UNCOMMITED)
      • 提交读(READ COMMITED)
      • 可重复读(REPEATABLE READ)
      • 可串行化(SERIALIZABLE)


事务处理语言 TCL

在这里插入图片描述

在进行数据操作的时候,往往会有很多不确定事件发生,这些事情通常都具有破坏性,导致数据不一致或者缺失等等。

有人在银行 ATM 机上取 5000 现金,点钱过程中突然断电了,只取出一部分,而卡中余额提示已经扣掉了 5000,怎么办?这种时候,我们就需要一种机制来保证数据结果的一致性。在数据库中,这个机制就叫做事务。

事务简介

事务(Transaction)是数据库操作的最小工作单元,是作为单个逻辑执行的一系列操作(比如上述中的输入取款金额,得到现金,取回磁卡等操作)的集合;这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行。事务是不可再分割的。

事务具有四大特征,即常说的 ACID:

  1. 原子性(Atomicity):事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做。
  2. 一致性(Consistency):事务执行的前后数据都处于合法状态,不会违背任何的数据完整性和逻辑的正确性,这就是“一致”的意思。以转账为例,转出账户的钱减少,但转入账户的钱没有增加,就不符合一致性。再以转账为例,无论多少个账户,多少个并行事务,其总数必然是一致的。原子性有助于保证数据的一致性,但不能完全保证。
  3. 隔离性(Isolation):一个事务的执行不能被其它事务所干扰,即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。换句话说,事务之间感知不到彼此的存在。
  4. 持续性(Durability):又叫永久性,指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。

事务控制

事务的控制是通过一系列控制语句来完成的,代表着事务的各个阶段。常用的控制语句如下表所示:

语句说明
BEGIN(START TRANSACTION)开始一个新的事务
SAVEPOINT设置事务的保存点
COMMIT提交事务
ROLLBACK回滚当前事务到初始状态,撤销提交前的操作
ROLLBACK TO SAVEPOINT name回滚当前事务到指定保存点 name,并撤销保存点后的操作
SET AUTOCOMMIT设置当前连接是否自动提交事务,1 表示启用自动提交,0 表示禁用自动提交
RELEASE SAVEPOINT释放保存点
SET TRANSACTION设置事务的隔离级别

查看当前事务是否设置了自动提交,其 SQL 语句如下:

select @@autocommit;

输出结果:

MariaDB [world]> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 |
+--------------+
1 row in set (0.000 sec)

该值为 1,即 MySQL 默认启用事务的自动提交模式,不用再输入提交命令。

为了突出事务的特点,笔者把事务提交方式设置为禁止自动提交。其 SQL 语句如下:

set autocommit = 0;

输出结果:

MariaDB [world]> set autocommit = 0;
Query OK, 0 rows affected (0.000 sec)

查看修改结果:

select @@autocommit;

输出结果:

MariaDB [world]> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            0 |
+--------------+
1 row in set (0.000 sec)

利用 DELETE 子句,把 city 表中 ID 为 1 的记录给删除掉,其 SQL 语句如下:

delete from city where id = 1;

输出结果:

MariaDB [world]> delete from city where id = 1;
Query OK, 1 row affected (0.000 sec)

接着查询 id 为 1 的记录此时是否存在,使用 SQL 语句如下:

select * from city where id = 1;

输出结果:

MariaDB [world]> select * from city where id = 1;
Empty set (0.000 sec)

从结果看,数据已经被删除,但此时事务并没有提交。所以当前对数据的操作还没有完全写入到数据库中,使用 ROLLBACK 来回滚事务,返回到该操作之前,其 SQL 语句如下:

rollback;

输出结果:

MariaDB [world]> rollback;
Query OK, 0 rows affected (0.001 sec)

再次查看 id 为 1 的记录是否存在,结果如下:

select * from city where id = 1;

输出结果:

MariaDB [world]> select * from city where id = 1;
+----+-------+-------------+----------+------------+
| ID | Name  | CountryCode | District | Population |
+----+-------+-------------+----------+------------+
|  1 | Kabul | AFG         | Kabol    |    1780000 |
+----+-------+-------------+----------+------------+
1 row in set (0.000 sec)

通过回滚操作,数据又回来了。只要在正式提交之前,都可以进行数据回滚。提交事务使用的控制语句是 COMMIT ,其 SQL 语句如下:

commit;

输出结果:

MariaDB [world]> commit;
Query OK, 0 rows affected (0.000 sec)

确保数据的修改无误后,使用 COMMIT 来提交数据,我们也把这种方式称为显示提交。 下面,演示一个比较简单的例子,来说明一下事务保存点的设置以及回滚等操作。

  1. 开始事务
  2. 然后在 city 表中插入一条记录
  3. 接着设置一个保存点
  4. 再插入一条记录
  5. 查看表内容变化情况
  6. 然后回滚到保存点
  7. 再次查看表内容
  8. 最后回滚到事务开始的地方
  9. 查看表内容,此时表内容和事务开始前是一样的,没有任何新的记录增加。

上面事务步骤翻译成 SQL 语句如下:

begin;

输出结果:
在这里插入图片描述

insert into city values(null,'test1','AFG','test1',101);

输出结果:
在这里插入图片描述

savepoint s1;

输出结果:
在这里插入图片描述

此处设置了保存点,取名为 s1。

insert into city values(null,'test2','AFG','test2',10001);

输出结果:
在这里插入图片描述

select * from city where countrycode = 'AFG';

输出结果:
在这里插入图片描述

此时可以看到,新插入的两条记录都显示出来了。

rollback to savepoint s1;

输出结果:
在这里插入图片描述

回滚到保存点 s1 位置处。

select * from city where countrycode = 'AFG';

输出结果:
在这里插入图片描述

可以看到设置保存点 s1 之后的操作(插入的第二条记录)已经实现回滚,数据没有了。

rollback;

输出结果:
在这里插入图片描述

此时回滚到了事务开始的地方,即 begin 位置处。

select * from city where countrycode = 'AFG';

输出结果:
在这里插入图片描述

再次查看结果,可以发现 city 表的内容和事务开始之前一模一样,没有任何变化。

并发事务的隔离挑战

事务并发是指多个事务同时对同一个数据进行操作。并发事务未做到隔离性,会带来以下问题:

脏读

一个事务读取到另一事务未提交的更新数据。当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中。这时,另外一个事务也访问这个数据,然后读到了修改后的数据,这个数据就是脏数据,依据脏数据所做的操作也是不正确的。例如 T1 开启了一个长事务,在较早的时间删除了一条记录,此时事务 T2 正好要统计表中记录总数,会少统计一条,随后 T1 事务发现删错了,进行了回滚操作,再随后 T2 事务再次统计,发现前后数据不一致。这显然违背了隔离性原则。

简单来说,脏读是指读到了未持久化的数据。

不可重复读

在同一事务中,多次读取同一数据返回的结果有所不同。换句话说,后续读取读到的是另一事务已提交的更新数据。例如 T1 开启了一个较长的事务,在较早的时间读取了一个数据,在中间另一个事务 T2 更改了数据并提交,随后 T1 再次读取但获得了新版本的数据,这时在同一个事务中多次读取同一数据却得到不同结果,这种现象就是不可重复读。显然,这也不符合隔离性原则。

幻读

在同一个事务中,以同样的条件进行范围查询,两次获得的记录数不一样。事务 T1 先执行了一次查询,然后事务 T2 新插入一行记录,接着 T1 使用相同的查询再次对表进行检索时,会发现这条出来的记录。这突然出现的记录就如一个“幻像”。 与“不可重复读”不同的是,幻读专指新插入的行。

那么如何来预防这些问题呢?

事务的隔离级别

为了防止上述问题,我们要对事务进行隔离。事务隔离有四个级别:

未提交读(READ-UNCOMMITED)

该级别的隔离性最弱,但并发性最好;事务中的修改,即使没有提交,对其他事务也都是可见的。也就是说事务可以读取未提交的数据,即产生脏读现象。

提交读(READ COMMITED)

一个事务提交后,它的变更才能被其他事务看到。大多数据库系统的默认级别,但 MySQL 不是。该级别的隔离可杜绝脏读,但仍会发生不可重复读。

可重复读(REPEATABLE READ)

MySQL 中事务的默认隔离级别。与“不可重复读”相反,“可重复读”是指在同一事务中多次读取同一数据时得到的都是事务开始那个时间点的数据版本,也可以理解为事务开始时对数据库拍了一个快照,后续操作都是在快照基础上进行的,自然不会读到别的事务的提交结果。

该级别直接针对不可重复读,但不能解决幻读。

可串行化(SERIALIZABLE)

当两个事务间存在读写冲突时,数据库通过加锁强制事务串行执行,解决了前面说的所有问题(脏读、不可重复读、幻读)。是最高的隔离级别。

名称含义脏读不可重复读幻读
未提交读一个事务提交前,它的变更就已经能被其他事务看到
读提交一个事务提交后,它的变更才能被其他事务看到×
可重复读未提交的事务的变更不能被其他事务看到,同时一次事务过程中多次读取同样记录的结果是一致的。××
可串行化当两个事务间存在读写冲突时,数据库通过加锁强制事务串行执行×××

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/609159.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

虹科案例 | 筒仓液位测量可以这么简单?

Part.01 行业挑战 在料箱、料斗或筒仓中使用散装物料的制造商需要准确可靠的液位检测来管理和处理库存,并最大限度地减少生产延迟。 塑料成型、食品加工和建筑材料等行业都依赖于散装材料。随着这些行业越来越接近准时制(JIT)制造&#xff…

认识协议【网络基础】

文章目录 什么是协议结构化数据结构化数据非结构化数据半结构化数据 结构化数据的传输序列化和反序列化 网络版计算器概述制定协议通过字符串传输结构化数据序列化与反序列化 实现计算器网络相关接口框架服务端客户端 制定协议请求响应发送和接收数据 计算逻辑测试存在的问题 T…

修改数组【并查集】

这里写自定义目录标题 并查集并查集的表示方法 题目输入描述输入示例输出示例 解题思路参考连接 并查集 并查集就是对集合的合并和查询操作的统称。他要求参与运算的两个集合是不相交的(不含有相同的元素)。针对这两个集合可以进行的操作: 1.合并:将两个…

复习之Linux系统中的进程管理

1.什么是进程?线程? 进程(Process):是操作系统进行资源分配的最小单位。一个进程是一个程序的一次执行过程。每启动一个进程,操作系统就会为它分配一块独立的内存空间,用于存储PCB、数据段、程…

如何从复盘中获得真正的收获?持续改进是关键!

复盘,本是围棋术语,每次博弈结束后,双方棋手把刚才的对局复演一遍,分析对局当中得失关键,提升自己棋力的好方法。复盘是对思维的训练。 通过复盘,当类似局面再次出现,你就能快速预测接下来的动态…

【网络】TCP套接字创建服务客户端与守护进程

文章目录 Tcp服务端TcpServer.hppTcpServer.cc Tcp客户端TcpClient.hppTcpClient.cc TCP客户端处理守护进程守护进程化 Tcp服务端 TcpServer.hpp TCP服务端创建流程如下: 创建socket文件套接字对象,面向字节流SOCK_STREAM bind绑定自己的网络信息&…

nacos注册中心配置springboot动态刷新源码解读

0丶简介 如何快速启动,请去官网看文档,言简意赅 https://nacos.io/zh-cn/docs/quick-start.html 只描述为何实现动态刷新的关键源码 1丶基于目前最新版本 <!-- https://mvnrepository.com/artifact/com.alibaba.boot/nacos-config-spring-boot-starter --> <depend…

命名管道详解

一、命名管道 1、命名管道与匿名管道一个很显著的区别是&#xff1a;匿名管道只能在有血缘关系的进程间进行通信&#xff0c;但命名管道可以让两个毫无关系的进程进行通信。 2、如果我们想在不相关的进程间交换数据&#xff0c;我们可以用到FIFO文件来进行通信&#xff0c;这…

【Nginx rewrite】

目录 一、常见的Nginx 正则表达式二、location1、location 解释2、location 示例说明&#xff1a;3、实际网站使用中&#xff0c;至少有三个匹配规则定义&#xff1a; 二、rewrite1、rewrite跳转实现&#xff1a;2、rewrite 执行顺序如下&#xff1a;3、rewrite 示例 一、常见的…

B-3:Linux 系统渗透提权

B-3&#xff1a;Linux 系统渗透提权 任务环境说明&#xff1a; 服务器场景&#xff1a;Server2204&#xff08;关闭链接&#xff09; 用户名&#xff1a;hacker 密码&#xff1a;123456 1.使用渗透机对服务器信息收集&#xff0c;并将服务器中 SSH 服务端口号作为 flag 提 …

Java工厂模式(随笔)

前言&#xff1a;Java工厂模式是一种创建型设计模式&#xff0c;它提供了一种将对象创建过程封装到一个单独的类中的方式&#xff0c;这个类就是被称为‘工厂类’&#xff0c;它根据特定的条件来决定应该创建哪个对象&#xff01; 文章目录&#xff1a; 三大工厂模式介绍特殊工…

计算机网络第二章——物理层(上)

提示&#xff1a;男儿何不带吴钩&#xff0c;收取关山五十州 文章目录 2.1.1 物理层基本概念知识引导物理层接口特征 2.1.2 数据通信基础知识数据通信相关术语数据通信系统要考虑的问题三种通信方式串行传输&并行传输同步传输&异步传输 脑图时刻 2.1.3 数据通信基础知识…

Google Play上架aab保姆级教程(纯aab上架/已上架apk转aab上架)

0、上传密钥 & 应用签名密钥 “Google 会使用上传证书验证您的身份&#xff0c;并使用您的应用签名密钥为 APK 签名以进行分发” 以上为官方解释。 2021年8月起&#xff0c;上传google play的应用必须以aab格式&#xff0c;aab的签名流程要比之前apk的复杂一些。需要上传…

如何真正有效地应对项目中的需求变更?

需求变更在奉行唯快不破的互联网公司&#xff0c;可算程序员头号噩梦&#xff0c;“996”直接元凶。 阿里口号拥抱变化。既然需求变更无法被消灭&#xff0c;就要通过学习&#xff0c;掌握更好应对需求变更方法。 1 常见的需求变更流程 先要发起变更申请&#xff0c;由变更委…

从IO多路复用到redis线程模型

文章目录 Unix IO模型分类阻塞IO - Blocking IO非阻塞IO - NoneBlocking IOIO多路复用 - IO multiplexing信号驱动IO - signal driven IO异步IO - asynchronous IO同步与异步的定义阻塞与非阻塞的定义 IO多路复用有哪些实现IO多路复用的大致实现selectpollepoll redis的线程模型…

Python实战基础19-异常处理及程序调试

1、异常概述 在程序运行过程中&#xff0c;经常会遇到各种各样的错误&#xff0c;这些错误统称为“异常”。 这些异常有的是由于开发者将关键字敲错&#xff0c;这类错误产生的是SyntaxError:invalid syntax&#xff08;无效语法&#xff09;&#xff0c;这将直接导致程序不能…

3.二进制高可用安装k8s 1.23集群(生产级)

二进制高可用安装k8s集群(生产级) 本文档适用于kubernetes1.23 节点 Etcd Cluster Etcd是一个数据库,k8s做的一些变更啥的都会存到Etcd中 如果集群比较大建议与master节点分装,单独装Etcd master节点 master分为几个重要的组件 你所有的流量都会经过Kube-APIServer Co…

排序算法——希尔排序图文详解

文章目录 希尔排序基本思想整体插入思想预排序结论 代码实现实现代码直接插入排序与希尔排序的效率比较测试代码&#xff1a; 时间复杂度 希尔排序 注1&#xff1a;本篇是基于对直接插入排序法的拓展&#xff0c;如果对直接插入法不了解&#xff0c;建议先看看直接插入排序 注…

Learning C++ No.27 【布隆过滤器实战】

引言 北京时间&#xff1a;2023/5/31/22:02&#xff0c;昨天的计算机导论考试&#xff0c;三个字&#xff0c;哈哈哈&#xff0c;摆烂&#xff0c;大致题目都是一些基础知识&#xff0c;但是这些基础知识都是非常非常理论的知识&#xff0c;理论的我一点不会&#xff0c;像什么…

【自制C++深度学习框架】表达式层的设计思路

表达式层的设计思路 在深度学习框架中&#xff0c;Expression Layer&#xff08;表达式层&#xff09;是指一个通用的算子&#xff0c;其允许深度学习网络的不同层之间结合和嵌套&#xff0c;从而支持一些更复杂的操作&#xff0c;如分支之间的加减乘除&#xff08;elementAdd…